Custom Sidebars – Dynamic Widget Area Manager - Version 3.0.0.0

Version Description

= 1.0 = Caution: Version 1.0 needs WordPress 3.3 to work. If you are running an earlier version do not upgrade.

= 0.7.1 = Now custom sidebars works with Thesis theme and some minor bugs have been solved.

= 0.7 = This version fix a bug of v0.6 and before that reset the custom sidebars of posts and pages when they are quick edited or bulk edited, so upgrade is recommended. This version also changes the capability for managing custom sidebars to 'switch_themes' the one that allows to see the appearance menu in the admin page. I think the plugin is more coherent this way, but anyway it is easy to modify under plugin edit.

= 0.6 = This version adds several options for customize the sidebars by categories and replace the default blog page sidebars. Now it's possible to edit sidebar properties. Also fixes some minor bugs.

Download this release

Release Info

Developer iworks
Plugin Icon 128x128 Custom Sidebars – Dynamic Widget Area Manager
Version 3.0.0.0
Comparing to
See all releases

Code changes from version 2.1.2.0 to 3.0.0.0

css/cs-cloning.css ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * CSS rules for the cloning module.
3
+ */
4
+ .inactive-sidebar .csb-clone {
5
+ display: none;
6
+ }
7
+
8
+ .widget-control-actions .csb-clone-button {
9
+ margin: 0 5px 0 0;
10
+ }
11
+
12
+ .csb-marker {
13
+ position: relative;
14
+ box-shadow: 0 0 0px 1px rgba(0, 0, 0, 0.3);
15
+ }
16
+
17
+ .csb-marker .widget-top,
18
+ .csb-marker .widget-inside {
19
+ opacity: .5;
20
+ }
21
+
22
+ .csb-marker:before {
23
+ content: attr(data-group);
24
+ position: absolute;
25
+ top: 50%;
26
+ left: 5px;
27
+ right: 5px;
28
+ text-align: center;
29
+ margin-top: -1em;
30
+ line-height: 2em;
31
+ height: 2em;
32
+ font-size: 20px;
33
+ z-index: 1001;
34
+ background: rgba(255, 255, 255, 0.2);
35
+ }
36
+
37
+ .csb-marker:after {
38
+ content: '';
39
+ position: absolute;
40
+ left: 1px;
41
+ top: 1px;
42
+ right: 1px;
43
+ bottom: 1px;
44
+ background: url(../img/stripes.png);
45
+ opacity: .05;
46
+ z-index: 1000;
47
+ cursor: default;
48
+ }
49
+
50
+ h4.csb-group {
51
+ padding-left: 45px;
52
+ position: relative;
53
+ }
54
+ h4 .btn-clone-group {
55
+ position: absolute;
56
+ top: 50%;
57
+ margin-top: -10px;
58
+ left: 15px;
59
+ cursor: pointer;
60
+ opacity: .6;
61
+ }
62
+ h4 .btn-clone-group:hover {
63
+ opacity: 1;
64
+ }
css/cs-cloning.min.css ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /*! Custom Sidebars - v2.1.08
2
+ * https://premium.wpmudev.org/project/custom-sidebars-pro/
3
+ * Copyright (c) 2016; * Licensed GPLv2+ */
4
+
5
+ .inactive-sidebar .csb-clone{display:none}.widget-control-actions .csb-clone-button{margin:0 5px 0 0}.csb-marker{position:relative;box-shadow:0 0 0 1px rgba(0,0,0,.3)}.csb-marker .widget-top,.csb-marker .widget-inside{opacity:.5}.csb-marker:before{content:attr(data-group);position:absolute;top:50%;left:5px;right:5px;text-align:center;margin-top:-1em;line-height:2em;height:2em;font-size:20px;z-index:1001;background:rgba(255,255,255,.2)}.csb-marker:after{content:'';position:absolute;left:1px;top:1px;right:1px;bottom:1px;background:url(../img/stripes.png);opacity:.05;z-index:1000;cursor:default}h4.csb-group{padding-left:45px;position:relative}h4 .btn-clone-group{position:absolute;top:50%;margin-top:-10px;left:15px;cursor:pointer;opacity:.6}h4 .btn-clone-group:hover{opacity:1}
css/cs-visibility.css ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * CSS rules for the visibility module.
3
+ */
4
+ .inactive-sidebar .csb-visibility {
5
+ display: none;
6
+ }
7
+
8
+ .widget-control-actions .csb-visibility-button {
9
+ margin: 0 5px 0 0;
10
+ }
11
+
12
+ .csb-visibility {
13
+ margin: 0 -15px 15px;
14
+ }
15
+
16
+ .csb-option-row {
17
+ margin: 0 -15px;
18
+ padding: 0 15px 12px;
19
+ position: relative;
20
+ }
21
+
22
+ .csb-visibility-inner {
23
+ border: 1px solid #E5E5E5;
24
+ border-left: 0;
25
+ border-right: 0;
26
+ padding: 12px 15px 0;
27
+ background: #FAFAFA;
28
+ }
29
+
30
+ .csb-visibility-inner .toggle-action {
31
+ display: block;
32
+ margin: -15px -15px 0;
33
+ padding: 15px 15px 0;
34
+ cursor: pointer;
35
+ border: 0;
36
+ /*color: #0074A2;*/
37
+ }
38
+
39
+ .csb-visibility-inner .csb-option-row:hover {
40
+ background: #F4F4F4;
41
+ /*color: #2EA2CC;*/
42
+ }
43
+
44
+ .csb-visibility-inner .csb-action {
45
+ margin-bottom: 0;
46
+ }
47
+
48
+ .csb-visibility-inner .csb-action label {
49
+ cursor: default;
50
+ }
51
+
52
+ .csb-visibility-inner .csb-action b {
53
+ padding: 5px;
54
+ border: 1px solid transparent;
55
+ cursor: pointer;
56
+ margin-left: -6px;
57
+ }
58
+
59
+ .csb-visibility-inner .csb-action:hover b {
60
+ padding: 5px;
61
+ background: #FFF;
62
+ border: 1px solid #DDD;
63
+ }
64
+
65
+ .csb-visibility-inner .csb-always {
66
+ padding-bottom: 0;
67
+ text-align: center;
68
+ font-style: italic;
69
+ }
70
+
71
+ .csb-visibility-inner .csb-always label {
72
+ margin-bottom: 0;
73
+ color: #AAA;
74
+ cursor: default;
75
+ }
76
+
77
+ .csb-visibility-inner .csb-option-row.csb-always:hover {
78
+ background: transparent;
79
+ }
80
+
81
+ .csb-visibility-inner .csb-and {
82
+ margin-right: 10px;
83
+ font-weight: bold;
84
+ }
85
+
86
+ .csb-visibility-inner label {
87
+ display: block;
88
+ border-top: 1px solid #E8E8E8;
89
+ margin: 0 -15px 5px;
90
+ padding: 5px 15px;
91
+ }
92
+
93
+ .csb-visibility-inner .csb-detail-row label {
94
+ border: 0;
95
+ margin-bottom: 0;
96
+ padding-bottom: 0;
97
+ }
98
+
99
+ .csb-visibility-inner .csb-detail-row .detail {
100
+ margin-top: 10px;
101
+ }
102
+
103
+ .csb-visibility-inner .chosen-container {
104
+ display: block !important;
105
+ width: 100% !important;
106
+ }
107
+
108
+ .csb-visibility-inner .csb-option-row .action {
109
+ position: absolute;
110
+ right: 15px;
111
+ top: 7px;
112
+ z-index: 1;
113
+ color: #AAA;
114
+ cursor: pointer;
115
+ font-size: 20px;
116
+ }
117
+
118
+ .csb-visibility-inner .csb-option-row .action:hover {
119
+ color: #000;
120
+ }
121
+
122
+ .csb-visibility-inner .csb-option-row.csb-action .action {
123
+ top: 15px;
124
+ }
125
+
126
+ .csb-visibility-inner .csb-option-row .clear-filter:hover {
127
+ color: #C00;
128
+ }
129
+
130
+ .csb-visibility-inner .csb-option-row .show-on-hover {
131
+ opacity: 0;
132
+ }
133
+
134
+ .csb-visibility-inner .csb-option-row:hover .show-on-hover {
135
+ opacity: 1;
136
+ }
137
+
138
+ .csb-visibility-inner .dropdown {
139
+ position: absolute;
140
+ z-index: 2;
141
+ background: #FFF;
142
+ border: 1px solid #DDD;
143
+ right: 10px;
144
+ top: 20px;
145
+ color: #555;
146
+ box-shadow: 0 1px 10px rgba(0, 0, 0, 0.15);
147
+ }
148
+
149
+ .csb-visibility-inner .dropdown li {
150
+ padding: 5px 15px;
151
+ cursor: pointer;
152
+ margin: 0;
153
+ }
154
+
155
+ .csb-visibility-inner .dropdown li:hover {
156
+ color: #000;
157
+ background: #EEE;
158
+ }
159
+
160
+ .csb-visibility-inner .dropdown li.csb-group,
161
+ .csb-visibility-inner .dropdown li.csb-group:hover {
162
+ color: #999;
163
+ font-weight: bold;
164
+ background: #F8F8F8;
165
+ padding-left: 5px;
166
+ cursor: default;
167
+ }
css/cs-visibility.min.css ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /*! Custom Sidebars - v2.1.08
2
+ * https://premium.wpmudev.org/project/custom-sidebars-pro/
3
+ * Copyright (c) 2016; * Licensed GPLv2+ */
4
+
5
+ .inactive-sidebar .csb-visibility{display:none}.widget-control-actions .csb-visibility-button{margin:0 5px 0 0}.csb-visibility{margin:0 -15px 15px}.csb-option-row{margin:0 -15px;padding:0 15px 12px;position:relative}.csb-visibility-inner{border:1px solid #E5E5E5;border-left:0;border-right:0;padding:12px 15px 0;background:#FAFAFA}.csb-visibility-inner .toggle-action{display:block;margin:-15px -15px 0;padding:15px 15px 0;cursor:pointer;border:0}.csb-visibility-inner .csb-option-row:hover{background:#F4F4F4}.csb-visibility-inner .csb-action{margin-bottom:0}.csb-visibility-inner .csb-action label{cursor:default}.csb-visibility-inner .csb-action b{padding:5px;border:1px solid transparent;cursor:pointer;margin-left:-6px}.csb-visibility-inner .csb-action:hover b{padding:5px;background:#FFF;border:1px solid #DDD}.csb-visibility-inner .csb-always{padding-bottom:0;text-align:center;font-style:italic}.csb-visibility-inner .csb-always label{margin-bottom:0;color:#AAA;cursor:default}.csb-visibility-inner .csb-option-row.csb-always:hover{background:transparent}.csb-visibility-inner .csb-and{margin-right:10px;font-weight:700}.csb-visibility-inner label{display:block;border-top:1px solid #E8E8E8;margin:0 -15px 5px;padding:5px 15px}.csb-visibility-inner .csb-detail-row label{border:0;margin-bottom:0;padding-bottom:0}.csb-visibility-inner .csb-detail-row .detail{margin-top:10px}.csb-visibility-inner .chosen-container{display:block!important;width:100%!important}.csb-visibility-inner .csb-option-row .action{position:absolute;right:15px;top:7px;z-index:1;color:#AAA;cursor:pointer;font-size:20px}.csb-visibility-inner .csb-option-row .action:hover{color:#000}.csb-visibility-inner .csb-option-row.csb-action .action{top:15px}.csb-visibility-inner .csb-option-row .clear-filter:hover{color:#C00}.csb-visibility-inner .csb-option-row .show-on-hover{opacity:0}.csb-visibility-inner .csb-option-row:hover .show-on-hover{opacity:1}.csb-visibility-inner .dropdown{position:absolute;z-index:2;background:#FFF;border:1px solid #DDD;right:10px;top:20px;color:#555;box-shadow:0 1px 10px rgba(0,0,0,.15)}.csb-visibility-inner .dropdown li{padding:5px 15px;cursor:pointer;margin:0}.csb-visibility-inner .dropdown li:hover{color:#000;background:#EEE}.csb-visibility-inner .dropdown li.csb-group,.csb-visibility-inner .dropdown li.csb-group:hover{color:#999;font-weight:700;background:#F8F8F8;padding-left:5px;cursor:default}
css/cs.css CHANGED
@@ -151,7 +151,6 @@
151
  .widgets-php .widget-liquid-left {
152
  width: 100%;
153
  }
154
-
155
  .widgets-php .widget-liquid-right {
156
  padding: 0 0 75px 0;
157
  margin: -10px -214% 0 0;
@@ -166,12 +165,22 @@
166
  .widgets-php .widget-liquid-right #widgets-right {
167
  margin: 20px;
168
  }
169
-
 
 
 
 
 
 
 
 
 
170
  .widgets-php #wpcontent {
171
  position: relative;
172
  }
173
- .widgets-php #wpcontent .wrap {
174
  margin-right: 68%;
 
175
  position: relative;
176
  }
177
  .widgets-php #wpcontent #screen-meta-links {
@@ -182,30 +191,77 @@
182
  position: relative;
183
  z-index: 10;
184
  }
185
-
186
  .widgets-php #widgets-left {
187
  margin-right: 0 !important;
188
  }
189
-
190
  .widgets-php #footer {
191
  background: #fff;
192
  margin-right: 0px;
193
  padding-right: 20px;
194
  }
195
-
196
- .widgets-php .wrap h2 {
197
- margin-bottom: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
198
  }
199
-
200
- .widget-liquid-right .overview {
201
- list-style: none;
202
- position: absolute;
203
- left: 0;
204
- top: 0;
205
- width: auto;
206
- right: 0;
207
- padding-left: 20px;
208
- border-left: 1px solid #DDD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  }
210
 
211
  #cs-options .cs-action {
151
  .widgets-php .widget-liquid-left {
152
  width: 100%;
153
  }
 
154
  .widgets-php .widget-liquid-right {
155
  padding: 0 0 75px 0;
156
  margin: -10px -214% 0 0;
165
  .widgets-php .widget-liquid-right #widgets-right {
166
  margin: 20px;
167
  }
168
+ .widgets-php .widget-liquid-right .overview {
169
+ list-style: none;
170
+ position: absolute;
171
+ left: 0;
172
+ top: 0;
173
+ width: auto;
174
+ right: 0;
175
+ padding-left: 20px;
176
+ border-left: 1px solid #DDD;
177
+ }
178
  .widgets-php #wpcontent {
179
  position: relative;
180
  }
181
+ .widgets-php #wpcontent .wrap .cs-wrap {
182
  margin-right: 68%;
183
+ padding-top: 1em;
184
  position: relative;
185
  }
186
  .widgets-php #wpcontent #screen-meta-links {
191
  position: relative;
192
  z-index: 10;
193
  }
 
194
  .widgets-php #widgets-left {
195
  margin-right: 0 !important;
196
  }
 
197
  .widgets-php #footer {
198
  background: #fff;
199
  margin-right: 0px;
200
  padding-right: 20px;
201
  }
202
+ .widgets-php .custom-sidebars-wp-checkup {
203
+ border-radius: 4px;
204
+ -ms-flex-align: center;
205
+ align-items: center;
206
+ background: #fff url(../img/heart.png) no-repeat 0 50%;
207
+ border: 0;
208
+ display: -ms-flexbox;
209
+ display: flex;
210
+ min-height: 100px;
211
+ padding-left: 135px;
212
+ -ms-flex-pack: justify;
213
+ justify-content: space-between;
214
+ }
215
+ .widgets-php .custom-sidebars-wp-checkup form {
216
+ white-space: nowrap;
217
  }
218
+ .widgets-php .custom-sidebars-wp-checkup form input {
219
+ border: 0;
220
+ border-radius: 4px;
221
+ }
222
+ .widgets-php .custom-sidebars-wp-checkup form input[type=text] {
223
+ background-color: #f2f2f2;
224
+ padding: 15px 14px;
225
+ }
226
+ .widgets-php .custom-sidebars-wp-checkup form input[type=submit] {
227
+ background-color: #17a8e3;
228
+ color: #fff;
229
+ padding: 15px 35px;
230
+ text-transform: uppercase;
231
+ margin-left: 10px;
232
+ }
233
+ .widgets-php .custom-sidebars-wp-checkup p {
234
+ font-size: 1.2em;
235
+ }
236
+ .widgets-php .custom-sidebars-wp-checkup p b {
237
+ color: #840006;
238
+ }
239
+ .widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront {
240
+ border-radius: 4px;
241
+ background-color: #f9c200;
242
+ margin: 55px 0 16px 0;
243
+ }
244
+ .widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .devman {
245
+ min-height: 145px;
246
+ margin-right: -16px;
247
+ background: url(../img/devman.png) no-repeat 100% 50%;
248
+ padding: 50px 120px 45px 20px;
249
+ }
250
+ .widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .devman p {
251
+ font-size: 1.4em;
252
+ color: #000;
253
+ margin-top: 0;
254
+ }
255
+ .widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .devman p:last-of-type {
256
+ margin-bottom: 0;
257
+ }
258
+ .widgets-php .sidebars-column-1 .inner .custom-sidebars-upfront .devman .button {
259
+ background-color: #00a7e6;
260
+ color: #fff;
261
+ font-weight: bold;
262
+ height: auto;
263
+ padding: 15px 16px;
264
+ text-transform: uppercase;
265
  }
266
 
267
  #cs-options .cs-action {
customsidebars.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Custom Sidebars
4
  * Plugin URI: https://wordpress.org/plugins/custom-sidebars/
5
  * Description: Allows you to create widgetized areas and custom sidebars. Replace whole sidebars or single widgets for specific posts and pages.
6
- * Version: 2.1.2.0
7
  * Author: WPMU DEV
8
  * Author URI: http://premium.wpmudev.org/
9
  * Textdomain: custom-sidebars
3
  * Plugin Name: Custom Sidebars
4
  * Plugin URI: https://wordpress.org/plugins/custom-sidebars/
5
  * Description: Allows you to create widgetized areas and custom sidebars. Replace whole sidebars or single widgets for specific posts and pages.
6
+ * Version: 3.0.0.0
7
  * Author: WPMU DEV
8
  * Author URI: http://premium.wpmudev.org/
9
  * Textdomain: custom-sidebars
img/devman.png ADDED
Binary file
img/frontpage-info.png CHANGED
Binary file
img/heart.png ADDED
Binary file
img/stripes.png CHANGED
Binary file
inc/class-custom-sidebars-advertisement.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_action( 'cs_init', array( 'CustomSidebarsAdvertisement', 'instance' ) );
4
+
5
+ /**
6
+ * Extends the widgets section to add the advertisements.
7
+ *
8
+ * @since 2.2.0
9
+ */
10
+ class CustomSidebarsAdvertisement extends CustomSidebars {
11
+
12
+ private $dismiss_name = 'custom_sidebars_advertisement_dismiss';
13
+ private $nonce_name = 'custom_sidebars_advertisement_nonce';
14
+
15
+ /**
16
+ * Returns the singleton object.
17
+ *
18
+ * @since 2.2.0
19
+ */
20
+ public static function instance() {
21
+ static $instance = null;
22
+
23
+ if ( null === $instance ) {
24
+ $instance = new CustomSidebarsAdvertisement();
25
+ }
26
+
27
+ return $instance;
28
+ }
29
+
30
+ /**
31
+ * Constructor is private -> singleton.
32
+ *
33
+ * @since 2.2.0
34
+ */
35
+ private function __construct() {
36
+ if ( ! is_admin() ) {
37
+ return;
38
+ }
39
+ wp_enqueue_script( 'wp-util' );
40
+ add_action( 'admin_head-widgets.php', array( $this, 'init_admin_head' ) );
41
+ add_action( 'wp_ajax_custom_sidebars_advertisement_dismiss', array( $this, 'dismiss' ) );
42
+ }
43
+
44
+ /**
45
+ * Save dismiss decision, no more show it.
46
+ *
47
+ * @since 2.2.0
48
+ */
49
+ public function dismiss() {
50
+ /**
51
+ * Check: is nonce send?
52
+ */
53
+ if ( ! isset( $_GET['_wpnonce'] ) ) {
54
+ die;
55
+ }
56
+ /**
57
+ * Check: is user id send?
58
+ */
59
+ if ( ! isset( $_GET['user_id'] ) ) {
60
+ die;
61
+ }
62
+ /**
63
+ * Check: nonce
64
+ */
65
+ $nonce_name = $this->nonce_name . $_GET['user_id'];
66
+ if ( ! wp_verify_nonce( $_GET['_wpnonce'], $nonce_name ) ) {
67
+ die;
68
+ }
69
+ /**
70
+ * save result
71
+ */
72
+ $result = add_user_meta( $_GET['user_id'], $this->dismiss_name, true, true );
73
+ if ( false == $result ) {
74
+ update_user_meta( $_GET['user_id'], $this->dismiss_name, true );
75
+ }
76
+ die;
77
+ }
78
+
79
+ /**
80
+ * Admin header
81
+ *
82
+ * @since 2.2.0
83
+ */
84
+ public function init_admin_head() {
85
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
86
+ }
87
+
88
+ /**
89
+ * Admin notice!
90
+ *
91
+ * @since 2.2.0
92
+ */
93
+ public function admin_notices() {
94
+ $user_id = get_current_user_id();
95
+ $url = add_query_arg(
96
+ array(
97
+ 'utm_source' => 'custom_sidebar_uf_ad',
98
+ 'utm_campaign' => 'custom_sidebar_plugin_uf_ad',
99
+ 'utm_medium' => 'Custom Sidebars Plugin',
100
+ ),
101
+ 'https://premium.wpmudev.org/projects/category/themes/'
102
+ );
103
+ ?>
104
+ <script type="text/javascript">
105
+ jQuery(document).on( 'click', '.custom-sidebars-wp-checkup .notice-dismiss', function() {
106
+ jQuery.ajax({
107
+ url: ajaxurl,
108
+ data: {
109
+ action: 'custom_sidebars_advertisement_dismiss',
110
+ _wpnonce: '<?php echo wp_create_nonce( $this->nonce_name . $user_id ) ?>',
111
+ user_id: <?php echo $user_id ?>
112
+ }
113
+ })
114
+ })
115
+ .ready( function() {
116
+ setTimeout( function() {
117
+ var template = wp.template('custom-sidebars-upfront');
118
+ jQuery(".sidebars-column-1 .inner").append( template() );
119
+ }, 1000);
120
+ });
121
+ </script>
122
+ <script type="text/html" id="tmpl-custom-sidebars-upfront">
123
+ <div class="custom-sidebars-upfront">
124
+ <div class="devman">
125
+ <p><?php esc_html_e( 'Don’t just replace sidebars. Add new sidebars and footers anywhere with Upfront.', 'custom-sidebars' ); ?></p>
126
+ <p><a class="button" href="<?php echo esc_url( $url ); ?>"><?php esc_html_e( 'get Upfront free', 'custom-sidebars' ); ?></a></p>
127
+ </div>
128
+ </div>
129
+ </script>
130
+ <div class="notice is-dismissible custom-sidebars-wp-checkup">
131
+ <p><?php _e( '<b>Warning:</b> Some of your plugins may be slowing down your site. Run a free security and performance scan with WP Checkup.', 'custom-sidebars' ); ?></p>
132
+ <form method="get" action="https://premium.wpmudev.org/wp-checkup/">
133
+ <input type="hidden" name="external-url" value="1" />
134
+ <input type="text" name="the-url" value="<?php echo esc_url( get_option( 'home' ) ); ?>" />
135
+ <input type="submit" value="<?php esc_attr_e( 'Scan', 'custom-sidebars' ); ?>" />
136
+ <input type="hidden" name="utm_source" value="custom_sidebar_ad" />
137
+ <input type="hidden" name="utm_campaign" value="custom_sidebar_plugin" />
138
+ <input type="hidden" name="utm_medium" value="Custom Sidebars Plugin" />
139
+ </form>
140
+ <button type="button" class="notice-dismiss">
141
+ <span class="screen-reader-text">Dismiss this notice.</span>
142
+ </button>
143
+ </div>
144
+ <?php
145
+ }
146
+ };
inc/class-custom-sidebars-cloning.php ADDED
@@ -0,0 +1,331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_action( 'cs_init', array( 'CustomSidebarsCloning', 'instance' ) );
4
+
5
+ /**
6
+ * Adds visibility options to all widgets:
7
+ * Clone a widget to quickly replicate its settings.
8
+ *
9
+ * @since 2.0
10
+ */
11
+ class CustomSidebarsCloning {
12
+
13
+ /**
14
+ * Buffer that holds data of a widget group.
15
+ * @see update_linked_widgets() // populate the property
16
+ * @see update_widget_group() // use the property
17
+ *
18
+ * @since 2.0
19
+ * @var bool|array
20
+ */
21
+ private $group_data = false;
22
+
23
+
24
+ /**
25
+ * Returns the singleton object.
26
+ *
27
+ * @since 2.0
28
+ */
29
+ public static function instance() {
30
+ static $Inst = null;
31
+
32
+ if ( null === $Inst ) {
33
+ $Inst = new CustomSidebarsCloning();
34
+ }
35
+
36
+ return $Inst;
37
+ }
38
+
39
+ /**
40
+ * Constructor is private -> singleton.
41
+ *
42
+ * @since 2.0
43
+ */
44
+ private function __construct() {
45
+ if ( is_admin() ) {
46
+ // in_widget_form: Add our button inside each widget.
47
+ add_action(
48
+ 'in_widget_form',
49
+ array( $this, 'admin_widget_button' ),
50
+ 10, 3
51
+ );
52
+
53
+ // in_widget_form: Update data of widget-group (see notes below).
54
+ add_action(
55
+ 'in_widget_form',
56
+ array( $this, 'update_widget_group' ),
57
+ 10, 3
58
+ );
59
+
60
+ // When the widget is saved (via Ajax) we save our options.
61
+ add_filter(
62
+ 'widget_update_callback',
63
+ array( $this, 'admin_widget_update' ),
64
+ 9999, 4
65
+ );
66
+
67
+ // Load the javascript support file for this module.
68
+ lib3()->ui->add( CSB_JS_URL . 'cs-cloning.min.js', 'widgets.php' );
69
+ lib3()->ui->add( CSB_CSS_URL . 'cs-cloning.css', 'widgets.php' );
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Extracts and sanitizes the CSB cloning data from the widget instance.
75
+ * Cloning data contains the parent widget.
76
+ *
77
+ * @since 2.0
78
+ * @param array $instance The widget instance data.
79
+ * @return array Sanitized CSB cloning data.
80
+ */
81
+ protected function get_widget_data( $instance ) {
82
+ $data = array();
83
+
84
+ if ( isset( $instance['csb_clone'] ) ) {
85
+ $data = $instance['csb_clone'];
86
+ }
87
+
88
+ if ( ! is_array( $data ) ) {
89
+ $data = array();
90
+ }
91
+
92
+ // group: ID of the group
93
+
94
+ if ( isset( $data['group'] ) && is_numeric( $data['group'] ) && $data['group'] > 0 ) {
95
+ $group = preg_replace( '/^.*-(\d+)$/', '$1', $data['group'] );
96
+ $state = @$data['state'];
97
+ } else {
98
+ $group = $this->new_group_id();
99
+ $state = 'new';
100
+ $data['group'] = intval( $group );
101
+ }
102
+
103
+ // state: ok|empty|new
104
+ if ( ! in_array( $state, array( 'ok', 'empty', 'new' ) ) ) {
105
+ $state = 'new';
106
+ }
107
+ $data['state'] = $state;
108
+
109
+ return $data;
110
+ }
111
+
112
+ /**
113
+ * Returns a new/unique group-ID.
114
+ *
115
+ * @since 2.0
116
+ */
117
+ protected function new_group_id() {
118
+ global $wp_registered_widgets;
119
+ static $Used_ids = null;
120
+ $group_id = 1;
121
+
122
+ if ( null === $Used_ids ) {
123
+ $Used_ids = array();
124
+
125
+ // Loop though all widgets to fetch used IDs.
126
+ foreach ( $wp_registered_widgets as $id => $data ) {
127
+ if ( ! isset( $data['callback'] ) ) { continue; }
128
+ if ( ! is_array( $data['callback'] ) ) { continue; }
129
+
130
+ $widget = reset( $data['callback'] );
131
+ $settings = false;
132
+ if ( is_object( $widget ) && method_exists( $widget, 'get_settings' ) ) {
133
+ $settings = $widget->get_settings();
134
+ }
135
+
136
+ // Check the database settings of the widget to find group IDs.
137
+ if ( is_array( $settings ) ) {
138
+ foreach ( $settings as $instance ) {
139
+ if ( ! isset( $instance['csb_clone'] ) ) { continue; }
140
+ if ( ! empty( $instance['csb_clone']['group'] ) ) {
141
+ $group = $instance['csb_clone']['group'];
142
+ if ( ! in_array( $group, $Used_ids ) ) {
143
+ $Used_ids[] = $group;
144
+ }
145
+ } // endif: empty(group)
146
+ } // endforeach
147
+ } // endif: is_array()
148
+ } // endforeach
149
+
150
+ }
151
+
152
+ // Find the first free group-ID.
153
+ while ( in_array( $group_id, $Used_ids ) ) {
154
+ $group_id += 1;
155
+ }
156
+ $Used_ids[] = $group_id;
157
+
158
+ return $group_id;
159
+ }
160
+
161
+ /**
162
+ * Finds the settings for the specified group inside the settings array.
163
+ *
164
+ * @since 2.0
165
+ */
166
+ protected function settings_for_group( $settings, $group ) {
167
+ if ( is_numeric( $group ) && $group > 0 ) {
168
+ foreach ( $settings as $data ) {
169
+ $item_group = @$data['csb_clone']['group'];
170
+ $item_status = @$data['csb_clone']['state'];
171
+
172
+ if ( $group == $item_group && 'ok' == $item_status ) {
173
+ return $data;
174
+ }
175
+ }
176
+ }
177
+ function_exists( 'wp_debug' ) && wp_debug( 'class-custom-sidebars-cloning.php:162', 'FAILED' );
178
+ return false;
179
+ }
180
+
181
+ /**
182
+ * Action handler for 'in_widget_form'
183
+ *
184
+ * @since 2.0
185
+ */
186
+ public function admin_widget_button( $widget, $return, $instance ) {
187
+ $data = $this->get_widget_data( $instance );
188
+ $is_linked = (0 != $data['group']);
189
+
190
+ ?>
191
+ <div class="csb-clone csb-clone-<?php echo esc_attr( $widget->id ); ?>">
192
+ <?php
193
+ /*
194
+ * This input is only used to determine if the "visibility" button
195
+ * should be displayed in the widget form.
196
+ */
197
+ ?>
198
+ <input type="hidden" name="csb-clone-button" value="0" />
199
+ <input type="hidden" name="csb_clone[group]" class="csb-clone-group" value="<?php echo esc_attr( $data['group'] ); ?>" />
200
+ <input type="hidden" name="csb_clone[state]" class="csb-clone-state" value="<?php echo esc_attr( $data['state'] ); ?>" />
201
+ <?php if ( ! isset( $_POST['csb-clone-button'] ) ) : ?>
202
+ <a href="#" class="button csb-clone-button"><?php _e( 'Clone', 'custom-sidebars' ); ?></a>
203
+ <?php else : ?>
204
+ <script>jQuery(function() { jQuery('.csb-clone-<?php echo esc_js( $widget->id ); ?>').closest('.widget').trigger('csb:update'); }); </script>
205
+ <?php endif; ?>
206
+
207
+ </div>
208
+ <?php
209
+ }
210
+
211
+ /**
212
+ * Action handler for 'in_widget_form'.
213
+ *
214
+ * The workflow for this function is not very obvious, it works like this:
215
+ * When a widget is saved it may update a number of other widgets that
216
+ * belong to the same widget-group (i.e. cloned widgets).
217
+ * However, the update function allows us to only change data of the updated
218
+ * widget - all changes made to other widgets will be overwritten by
219
+ * WordPress after the widget_update_callback filter is executed.
220
+ *
221
+ * So the widget_update_callback filter will save the modified widget data
222
+ * inside the property $this->group_data. {@see update_linked_widgets}
223
+ *
224
+ * After the widget_update_callback filter is called the widget is rendered
225
+ * again. Now the in_widget_form hook is called. It is not related to saving
226
+ * the widget but provides a way to update the settings in chronolically
227
+ * correct order, this is why we hijack it for saving settings...
228
+ *
229
+ * @since 2.0
230
+ */
231
+ public function update_widget_group( $widget, $return, $instance ) {
232
+ if ( ! empty( $this->group_data ) ) {
233
+ $widget->save_settings( $this->group_data );
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Apply cloning logic when user saves the widget.
239
+ *
240
+ * @since 2.0
241
+ * @param array $new_instance New settings for this instance as input by the user.
242
+ * @param array $old_instance Old settings for this instance.
243
+ * @param WP_Widget $widget The current widget instance.
244
+ * @return array Modified settings.
245
+ */
246
+ public function admin_widget_update( $instance, $new_instance, $old_instance, $widget ) {
247
+ $data = $this->get_widget_data( $_POST );
248
+
249
+ $instance['csb_clone'] = $data;
250
+ $settings = $widget->get_settings();
251
+ $my_id = $widget->number;
252
+
253
+ switch ( @$instance['csb_clone']['state'] ) {
254
+ case 'empty':
255
+ return $this->populate_widget( $my_id, $settings, $instance, $widget );
256
+ break;
257
+
258
+ case 'ok':
259
+ return $this->update_linked_widgets( $my_id, $settings, $instance, $widget );
260
+ break;
261
+
262
+ default:
263
+ $instance['csb_clone']['state'] = 'ok';
264
+ return $instance;
265
+ }
266
+ }
267
+
268
+ /**
269
+ * This function returns the $instance data of a new clone. The data is
270
+ * populated with the values of the widget-group.
271
+ */
272
+ protected function populate_widget( $id, $settings, $instance, $widget ) {
273
+ $instance['csb_clone']['state'] = 'ok';
274
+
275
+ if ( ! isset( $instance['csb_clone']['group'] ) ) {
276
+ // Widget does not have any cloning information.
277
+ return $instance;
278
+ }
279
+
280
+ $group = $instance['csb_clone']['group'];
281
+ if ( empty( $group ) ) {
282
+ // Widget does not have a group (anymore).
283
+ return $instance;
284
+ }
285
+
286
+ $group_data = $this->settings_for_group( $settings, $group );
287
+ if ( empty( $group_data ) ) {
288
+ // The specified group does not exist (anymore).
289
+ return $instance;
290
+ }
291
+
292
+ // Success, fetch the config from group!
293
+ $instance = $group_data;
294
+ return $instance;
295
+ }
296
+
297
+ /**
298
+ * Update ALL widgets in the same group as the specified widget.
299
+ */
300
+ protected function update_linked_widgets( $id, $settings, $instance, $widget ) {
301
+ $instance['csb_clone']['state'] = 'ok';
302
+ $group_data = $instance;
303
+ $my_group = @$group_data['csb_clone']['group'];
304
+
305
+ foreach ( $settings as $key => $the_inst ) {
306
+ if ( ! isset( $the_inst['csb_clone']['group'] ) ) {
307
+ // Widget does not have any cloning information.
308
+ continue;
309
+ }
310
+
311
+ $group = $the_inst['csb_clone']['group'];
312
+ if ( empty( $group ) ) {
313
+ // Widget does not have a group (anymore).
314
+ continue;
315
+ }
316
+
317
+ if ( $group != $my_group ) {
318
+ // This widget does not belong to the current group.
319
+ continue;
320
+ }
321
+
322
+ // Success, this widget needs to be updated!
323
+ $settings[ $key ] = $group_data;
324
+ }
325
+
326
+ $settings[ $id ] = $group_data;
327
+ $this->group_data = $settings;
328
+
329
+ return $instance;
330
+ }
331
+ };
inc/class-custom-sidebars-editor.php CHANGED
@@ -47,7 +47,32 @@ class CustomSidebarsEditor extends CustomSidebars {
47
  array( $this, 'handle_ajax' )
48
  );
49
 
50
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
  }
53
 
@@ -206,7 +231,7 @@ class CustomSidebarsEditor extends CustomSidebars {
206
  }
207
 
208
  // Populate the sidebar object.
209
- if ( ! CSB_IS_PRO ) {
210
  $sidebar['name'] = $sb_name;
211
  $sidebar['description'] = $sb_desc;
212
  } else {
@@ -252,7 +277,9 @@ class CustomSidebarsEditor extends CustomSidebars {
252
  $req->data = $sidebar;
253
  $req->action = $action;
254
 
255
-
 
 
256
 
257
  return $req;
258
  }
@@ -358,7 +385,13 @@ class CustomSidebarsEditor extends CustomSidebars {
358
  );
359
 
360
  $raw_authors = array();
361
-
 
 
 
 
 
 
362
 
363
  // Collect required data for all posttypes.
364
  $posttypes = array();
@@ -415,7 +448,17 @@ class CustomSidebarsEditor extends CustomSidebars {
415
  );
416
  }
417
 
418
-
 
 
 
 
 
 
 
 
 
 
419
 
420
  $req->replaceable = $defaults['modifiable'];
421
  $req->posttypes = $posttypes;
@@ -461,7 +504,13 @@ class CustomSidebarsEditor extends CustomSidebars {
461
  );
462
 
463
  $raw_authors = array();
464
-
 
 
 
 
 
 
465
 
466
  // == Update the options
467
 
@@ -536,7 +585,21 @@ class CustomSidebarsEditor extends CustomSidebars {
536
  }
537
  }
538
 
539
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  }
541
 
542
  $req->message = sprintf(
@@ -682,5 +745,262 @@ class CustomSidebarsEditor extends CustomSidebars {
682
  self::set_post_meta( $post_id, $data );
683
  }
684
 
685
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
686
  };
47
  array( $this, 'handle_ajax' )
48
  );
49
 
50
+ // Add a custom column to post list.
51
+ $posttypes = self::get_post_types( 'objects' );
52
+ foreach ( $posttypes as $pt ) {
53
+ add_filter(
54
+ 'manage_' . $pt->name . '_posts_columns',
55
+ array( $this, 'post_columns' )
56
+ );
57
+
58
+ add_action(
59
+ 'manage_' . $pt->name . '_posts_custom_column',
60
+ array( $this, 'post_column_content' ),
61
+ 10, 2
62
+ );
63
+ }
64
+
65
+ add_action(
66
+ 'quick_edit_custom_box',
67
+ array( $this, 'post_quick_edit' ),
68
+ 10, 2
69
+ );
70
+
71
+ add_action(
72
+ 'admin_footer',
73
+ array( $this, 'post_quick_edit_js' )
74
+ );
75
+
76
  }
77
  }
78
 
231
  }
232
 
233
  // Populate the sidebar object.
234
+ if ( 'insert' == $action || self::wpml_is_default_lang() ) {
235
  $sidebar['name'] = $sb_name;
236
  $sidebar['description'] = $sb_desc;
237
  } else {
277
  $req->data = $sidebar;
278
  $req->action = $action;
279
 
280
+ // Allow user to translate sidebar name/description via WPML.
281
+ self::wpml_update( $sidebars );
282
+ $req->data = self::wpml_translate( $sidebar );
283
 
284
  return $req;
285
  }
385
  );
386
 
387
  $raw_authors = array();
388
+ $raw_authors = get_users(
389
+ array(
390
+ 'order_by' => 'display_name',
391
+ 'fields' => array( 'ID', 'display_name' ),
392
+ 'who' => 'authors',
393
+ )
394
+ );
395
 
396
  // Collect required data for all posttypes.
397
  $posttypes = array();
448
  );
449
  }
450
 
451
+ // Build a list of authors.
452
+ $authors = array();
453
+ foreach ( $raw_authors as $user ) {
454
+ $sel_archive = @$defaults['author_archive'][ @$user->ID ];
455
+
456
+ $authors[ @$user->ID ] = array(
457
+ 'name' => @$user->display_name,
458
+ 'archive' => self::get_array( $sel_archive ),
459
+ );
460
+ }
461
+ $req->authors = $authors;
462
 
463
  $req->replaceable = $defaults['modifiable'];
464
  $req->posttypes = $posttypes;
504
  );
505
 
506
  $raw_authors = array();
507
+ $raw_authors = get_users(
508
+ array(
509
+ 'order_by' => 'display_name',
510
+ 'fields' => array( 'ID', 'display_name' ),
511
+ 'who' => 'authors',
512
+ )
513
+ );
514
 
515
  // == Update the options
516
 
585
  }
586
  }
587
 
588
+ // Author settings.
589
+ foreach ( $raw_authors as $user ) {
590
+ $key = $user->ID;
591
+ if (
592
+ is_array( @$data['arc-aut'][ $sb_id ] ) &&
593
+ in_array( $key, $data['arc-aut'][ $sb_id ] )
594
+ ) {
595
+ $options['author_archive'][ $key ][ $sb_id ] = $req->id;
596
+ } elseif (
597
+ isset( $options['author_archive'][ $key ][ $sb_id ] ) &&
598
+ $options['author_archive'][ $key ][ $sb_id ] == $req->id
599
+ ) {
600
+ unset( $options['author_archive'][ $key ][ $sb_id ] );
601
+ }
602
+ }
603
  }
604
 
605
  $req->message = sprintf(
745
  self::set_post_meta( $post_id, $data );
746
  }
747
 
748
+ // ========== WPML support.
749
+
750
+ /**
751
+ * Updates the WPML string register with the current sidebar string so the
752
+ * user can translate the sidebar details using the WPML string translation.
753
+ *
754
+ * @since 2.0.9.7
755
+ * @param array $custom_sidebars List of the custom sidebars.
756
+ */
757
+ static protected function wpml_update( $custom_sidebars ) {
758
+ if ( ! function_exists( 'icl_register_string' ) ) { return false; }
759
+
760
+ $theme_sidebars = self::get_sidebars();
761
+
762
+ // This is used to identify the sidebar-translations by WPML.
763
+ $context = 'Sidebar';
764
+
765
+ // First do the theme sidebars, so they will be displayed in the
766
+ // *bottom* of the translations list.
767
+ foreach ( $theme_sidebars as $fields ) {
768
+ self::wpml_update_field( $context, $fields['id'] . '-name', @$fields['name'], false );
769
+ self::wpml_update_field( $context, $fields['id'] . '-description', @$fields['description'], false );
770
+ }
771
+
772
+ foreach ( $custom_sidebars as $fields ) {
773
+ $name = isset( $fields['name_lang'] ) ? $fields['name_lang'] : $fields['name'];
774
+ $description = isset( $fields['description_lang'] ) ? $fields['description_lang'] : $fields['description'];
775
+ self::wpml_update_field( $context, $fields['id'] . '-name', $name, true );
776
+ self::wpml_update_field( $context, $fields['id'] . '-description', $description, true );
777
+ }
778
+ }
779
+
780
+ /**
781
+ * Updates the WPML string register for a single field.
782
+ *
783
+ * @since 2.0.9.7
784
+ * @param string $context
785
+ * @param string $field
786
+ * @param string $value
787
+ * @param bool $update_string If false then the translation will only be
788
+ * registered but not updated.
789
+ */
790
+ static protected function wpml_update_field( $context, $field, $value, $update_string = true ) {
791
+ global $sitepress, $sitepress_settings;
792
+
793
+ if ( empty( $sitepress ) || empty( $sitepress_settings ) ) { return false; }
794
+ if ( ! function_exists( 'icl_t' ) ) { return false; }
795
+
796
+ if ( ! icl_st_is_registered_string( $context, $field ) ) {
797
+ // Register the field if it does not exist.
798
+ icl_register_string( $context, $field, $value, false );
799
+
800
+ $active_languages = $sitepress->get_active_languages();
801
+
802
+ foreach ( $active_languages as $lang => $data ) {
803
+ icl_update_string_translation( $field, $lang, $value, ICL_STRING_TRANSLATION_COMPLETE );
804
+ }
805
+
806
+ $default_language = ! empty( $sitepress_settings['st']['strings_language'] )
807
+ ? $sitepress_settings['st']['strings_language']
808
+ : $sitepress->get_default_language();
809
+ icl_update_string_translation( $field, $default_language, $value, ICL_STRING_TRANSLATION_COMPLETE );
810
+
811
+ } else if ( $update_string ) {
812
+
813
+ // Add translation.
814
+ if ( defined( 'DOING_AJAX' ) ) {
815
+ $current_language = $sitepress->get_language_cookie();
816
+ } else {
817
+ $current_language = $sitepress->get_current_language();
818
+ }
819
+
820
+ icl_update_string_translation( $field, $current_language, $value, ICL_STRING_TRANSLATION_COMPLETE );
821
+ }
822
+ }
823
+
824
+ /**
825
+ * Returns boolean true, when site is currently using the default language.
826
+ *
827
+ * @since 2.0.9.7
828
+ * @return bool
829
+ */
830
+ static protected function wpml_is_default_lang() {
831
+ global $sitepress, $sitepress_settings;
832
+ if ( empty( $sitepress ) || empty( $sitepress_settings ) ) { return true; }
833
+ if ( ! function_exists( 'icl_t' ) ) { return true; }
834
+
835
+ if ( defined( 'DOING_AJAX' ) ) {
836
+ $current_language = $sitepress->get_language_cookie();
837
+ } else {
838
+ $current_language = $sitepress->get_current_language();
839
+ }
840
+
841
+ $default_language = ! empty( $sitepress_settings['st']['strings_language'] )
842
+ ? $sitepress_settings['st']['strings_language']
843
+ : $sitepress->get_default_language();
844
+
845
+ return $default_language == $current_language;
846
+ }
847
+
848
+ /**
849
+ * Translates the text inside the specified sidebar object.
850
+ *
851
+ * @since 2.0.9.7
852
+ * @param array $sidebar Sidebar object.
853
+ * @return array Translated sidebar object.
854
+ */
855
+ static protected function wpml_translate( $sidebar ) {
856
+ if ( ! function_exists( 'icl_t' ) ) { return $sidebar; }
857
+
858
+ $context = 'Sidebar';
859
+
860
+ // Translate the name and description.
861
+ // Note: When changing a translation the icl_t() function will not
862
+ // return the updated value due to caching.
863
+
864
+ if ( isset( $sidebar['name_lang'] ) ) {
865
+ $sidebar['name'] = $sidebar['name_lang'];
866
+ } else {
867
+ $sidebar['name'] = icl_t( $context, $sidebar['id'] . '-name', $sidebar['name'] );
868
+ }
869
+ if ( isset( $sidebar['description_lang'] ) ) {
870
+ $sidebar['description'] = $sidebar['description_lang'];
871
+ } else {
872
+ $sidebar['description'] = icl_t( $context, $sidebar['id'] . '-description', $sidebar['description'] );
873
+ }
874
+
875
+ return $sidebar;
876
+ }
877
+
878
+
879
+ //
880
+ // ========== Custom column an Quick-Edit fields for post list.
881
+ // http://shibashake.com/wordpress-theme/expand-the-wordpress-quick-edit-menu
882
+ //
883
+
884
+ /**
885
+ * Adds a custom column to post-types that support custom sidebars.
886
+ *
887
+ * @since 2.0.9.7
888
+ * @param array $columns Column list.
889
+ * @return array Modified column list.
890
+ */
891
+ public function post_columns( $columns ) {
892
+ // This column is added.
893
+ $insert = array(
894
+ 'cs_replacement' => __( 'Custom Sidebars', 'custom-sidebars' ),
895
+ );
896
+
897
+ // Column is added after column 'title'.
898
+ $insert_after = 'title';
899
+
900
+ $pos = array_search( $insert_after, array_keys( $columns ) ) + 1;
901
+ $columns = array_merge(
902
+ array_slice( $columns, 0, $pos ),
903
+ $insert,
904
+ array_slice( $columns, $pos )
905
+ );
906
+
907
+ return $columns;
908
+ }
909
+
910
+ /**
911
+ * Display values in the custom column.
912
+ *
913
+ * @since 2.0.9.7
914
+ * @param string $column_name Column-Key defined in post_columns above.
915
+ * @param int $post_id Post-ID
916
+ */
917
+ public function post_column_content( $column_name, $post_id ) {
918
+ switch ( $column_name ) {
919
+ case 'cs_replacement':
920
+ $this->print_sidebars_form( $post_id, 'col-sidebars' );
921
+ break;
922
+ }
923
+ }
924
+
925
+ /**
926
+ * Adds a custom field to the quick-edit box to select custom columns.
927
+ *
928
+ * @since 2.0.9.7
929
+ * @param string $column_name Column-Key defined in post_columns above.
930
+ * @param string $post_type Post-type that is currently edited.
931
+ */
932
+ public function post_quick_edit( $column_name, $post_type ) {
933
+ if ( ! self::supported_post_type( $post_type ) ) { return false; }
934
+
935
+ switch ( $column_name ) {
936
+ case 'cs_replacement':
937
+ $this->print_metabox_quick();
938
+ break;
939
+ }
940
+ }
941
+
942
+ /**
943
+ * Javascript to set the values of the quick-edit form.
944
+ *
945
+ * Note: There is only 1 quick-edit form on the page. The form is displayed
946
+ * when the user clicks the quick edit action; all fields are then populated
947
+ * with values of the corresponding post.
948
+ *
949
+ * @since 2.0.9.7
950
+ */
951
+ public function post_quick_edit_js() {
952
+ global $current_screen;
953
+
954
+ if ( ( $current_screen->base != 'edit' ) ) { return false; }
955
+ if ( ! self::supported_post_type( $current_screen->post_type ) ) { return false; }
956
+
957
+ ?>
958
+ <script type="text/javascript">
959
+ <!--
960
+ jQuery(function() {
961
+ // we create a copy of the WP inline edit post function
962
+ var wp_inline_edit = inlineEditPost.edit;
963
+
964
+ // and then we overwrite the function with our own code
965
+ inlineEditPost.edit = function( id ) {
966
+
967
+ // "call" the original WP edit function
968
+ // we don't want to leave WordPress hanging
969
+ wp_inline_edit.apply( this, arguments );
970
+
971
+ // now we take care of our business.
972
+
973
+ // get the post ID
974
+ var post_id = 0;
975
+ if ( typeof( id ) == 'object' ) {
976
+ post_id = parseInt( this.getId( id ) );
977
+ }
978
+
979
+ if ( post_id > 0 ) {
980
+
981
+ // define the edit row
982
+ var edit_row = jQuery( '#edit-' + post_id );
983
+ var post_row = jQuery( '#post-' + post_id );
984
+
985
+ // Our custom column
986
+ var sidebar_col = post_row.find( '.cs_replacement' );
987
+
988
+ sidebar_col.find( '[data-sidebar]' ).each(function() {
989
+ var key = jQuery( this ).attr( 'data-sidebar' ),
990
+ val = jQuery( this ).attr( 'data-replaced' ),
991
+ hide = 'yes' === jQuery( this ).attr( 'data-cshide' );
992
+
993
+ if ( hide ) {
994
+ edit_row.find( '.cs-replacement-field.' + key ).val( val ).parent().hide();
995
+ } else {
996
+ edit_row.find( '.cs-replacement-field.' + key ).val( val ).parent().show();
997
+ }
998
+ });
999
+ }
1000
+ };
1001
+ });
1002
+ //-->
1003
+ </script>
1004
+ <?php
1005
+ }
1006
  };
inc/class-custom-sidebars-export.php ADDED
@@ -0,0 +1,810 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_action( 'cs_init', array( 'CustomSidebarsExport', 'instance' ) );
4
+
5
+ /**
6
+ * Provides functionality to export and import sidebar settings.
7
+ *
8
+ * @since 2.0
9
+ */
10
+ class CustomSidebarsExport extends CustomSidebars {
11
+
12
+ // Holds the contents of the import-file during preview/import.
13
+ static private $import_data = null;
14
+
15
+ // Used after preview. This holds only the items that were selected for import.
16
+ private $selected_data = null;
17
+
18
+
19
+ /**
20
+ * Returns the singleton object.
21
+ *
22
+ * @since 2.0
23
+ */
24
+ public static function instance() {
25
+ static $Inst = null;
26
+
27
+ if ( null === $Inst ) {
28
+ $Inst = new CustomSidebarsExport();
29
+ }
30
+
31
+ return $Inst;
32
+ }
33
+
34
+ /**
35
+ * Constructor is private -> singleton.
36
+ *
37
+ * @since 2.0
38
+ */
39
+ private function __construct() {
40
+ if ( is_admin() ) {
41
+ add_action(
42
+ 'cs_widget_header',
43
+ array( $this, 'widget_header' )
44
+ );
45
+
46
+ add_action(
47
+ 'cs_ajax_request',
48
+ array( $this, 'handle_ajax' )
49
+ );
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Called by action 'cs_widget_header'. Output the export/import button in
55
+ * the widget header.
56
+ *
57
+ * @since 2.0
58
+ */
59
+ public function widget_header() {
60
+ ?>
61
+ <a href="#" class="cs-action btn-export"><?php _e( 'Import / Export Sidebars', 'custom-sidebars' ); ?></a>
62
+ <?php
63
+ }
64
+
65
+ /**
66
+ * When the custom sidebars section is visible we see if export-action
67
+ * needs to be processed.
68
+ *
69
+ * @since 2.0
70
+ */
71
+ public function handle_ajax( $ajax_action ) {
72
+ $req = (object) array(
73
+ 'status' => 'ERR',
74
+ );
75
+ $is_json = true;
76
+ $handle_it = false;
77
+ $view_file = '';
78
+
79
+ switch ( $ajax_action ) {
80
+ case 'export':
81
+ case 'import':
82
+ case 'preview-import':
83
+ $handle_it = true;
84
+ $req->status = 'OK';
85
+ $req->action = $ajax_action;
86
+ break;
87
+ }
88
+
89
+ // The ajax request was not meant for us...
90
+ if ( ! $handle_it ) {
91
+ return false;
92
+ }
93
+
94
+ if ( ! current_user_can( self::$cap_required ) ) {
95
+ $req = self::req_err(
96
+ $req,
97
+ __( 'You do not have permission for this', 'custom-sidebars' )
98
+ );
99
+ } else {
100
+ switch ( $ajax_action ) {
101
+ case 'export':
102
+ $this->download_export_file();
103
+ break;
104
+
105
+ case 'preview-import':
106
+ $req = $this->read_import_file( $req );
107
+ if ( 'OK' == $req->status ) {
108
+ ob_start();
109
+ include CSB_VIEWS_DIR . 'import.php';
110
+ $req->html = ob_get_clean();
111
+ }
112
+ break;
113
+
114
+ case 'import':
115
+ $req = $this->prepare_import_data( $req );
116
+ break;
117
+ }
118
+ }
119
+
120
+ // Make the ajax response either as JSON or plain text.
121
+ if ( $is_json ) {
122
+ self::json_response( $req );
123
+ } else {
124
+ ob_start();
125
+ include CSB_VIEWS_DIR . $view_file;
126
+ $resp = ob_get_clean();
127
+
128
+ self::plain_response( $resp );
129
+ }
130
+ }
131
+
132
+
133
+ /*============================*\
134
+ ================================
135
+ == ==
136
+ == EXPORT ==
137
+ == ==
138
+ ================================
139
+ \*============================*/
140
+
141
+
142
+ /**
143
+ * Collects the plugin details for export.
144
+ *
145
+ * @since 2.0
146
+ */
147
+ private function get_export_data() {
148
+ global $wp_registered_widgets, $wp_version;
149
+
150
+ $theme = wp_get_theme();
151
+
152
+ $csb_info = get_plugin_data( CSB_PLUGIN );
153
+
154
+ $data = array();
155
+ // Add some meta-details to the export file.
156
+ $data['meta'] = array(
157
+ 'created' => time(),
158
+ 'wp_version' => $wp_version,
159
+ 'csb_version' => @$csb_info['Version'],
160
+ 'theme_name' => $theme->get( 'Name' ),
161
+ 'theme_version' => $theme->get( 'Version' ),
162
+ 'description' => htmlspecialchars( @$_POST['export-description'] ),
163
+ );
164
+
165
+ // Export the custom sidebars.
166
+ $data['sidebars'] = self::get_custom_sidebars();
167
+
168
+ // Export the sidebar options (e.g. default replacement).
169
+ $data['options'] = self::get_options();
170
+
171
+ // Export category-information.
172
+ $data['categories'] = get_categories( array( 'hide_empty' => 0 ) );
173
+
174
+ /*
175
+ * Export all widget options.
176
+ *
177
+ * $wp_registered_widgets contains all widget-instances that were placed
178
+ * inside a sidebar. So we loop this array and fetch each widgets
179
+ * options individually:
180
+ *
181
+ * Widget options are saved inside options table with option_name
182
+ * "widget_<widget-slug>"; the options can be an array, e.g.
183
+ * "widget_search" contains options for all widget instances in any
184
+ * sidebar. When we place 2 search widgets in different sidebars there
185
+ * will be a list with two option-arrays.
186
+ */
187
+ $data['widgets'] = array();
188
+ foreach ( self::get_sidebar_widgets() as $sidebar => $widgets ) {
189
+ if ( 'wp_inactive_widgets' === $sidebar ) {
190
+ continue;
191
+ }
192
+ if ( is_array( $widgets ) ) {
193
+ $data['widgets'][ $sidebar ] = array();
194
+ foreach ( $widgets as $widget_id ) {
195
+ if ( isset( $wp_registered_widgets[ $widget_id ] ) ) {
196
+ $item = $wp_registered_widgets[ $widget_id ];
197
+ $cb = $item['callback'];
198
+ $widget = is_array( $cb ) ? reset( $cb ) : false;
199
+ $id = $widget_id;
200
+ if ( ! isset( $data['widgets'][ $sidebar ][ $id ] ) ) {
201
+ if ( preg_match( '/(\d+)$/', $widget_id, $matches ) ) {
202
+ $id = $matches[1];
203
+ }
204
+ }
205
+ if ( isset( $data['widgets'][ $sidebar ][ $id ] ) ) {
206
+ continue;
207
+ }
208
+ if ( is_object( $widget ) && method_exists( $widget, 'get_settings' ) ) {
209
+ /**
210
+ * set correct widget data
211
+ */
212
+ $widget->id = $widget_id;
213
+ $widget->number = $id;
214
+ /**
215
+ * get settings
216
+ */
217
+ $settings = $widget->get_settings();
218
+ $data['widgets'][ $sidebar ][ $id ] = array(
219
+ 'name' => @$widget->name,
220
+ 'classname' => get_class( $widget ),
221
+ 'id_base' => @$widget->id_base,
222
+ 'description' => @$widget->description,
223
+ 'settings' => $settings[ @$widget->number ],
224
+ 'version' => 3,
225
+ );
226
+ } else {
227
+ /**
228
+ * Widgets that are registered with the old widget API
229
+ * have a different structure:
230
+ *
231
+ * - Not an object but a callback function.
232
+ * - No standard options-form.
233
+ * -> No widget settings to export.
234
+ * -> No clone/visibility options to export.
235
+ * - Only one instance
236
+ * -> "id_base" is same as $widget_id
237
+ */
238
+ $data['widgets'][ $sidebar ][ $widget_id ] = array(
239
+ 'name' => @$item['name'],
240
+ 'classname' => @$item['classname'],
241
+ 'id_base' => @$item['id'],
242
+ 'description' => @$item['description'],
243
+ 'settings' => @$item['params'],
244
+ 'version' => 2,
245
+ );
246
+ }
247
+ /**
248
+ * remove empty settings
249
+ */
250
+ if ( isset( $data['widgets'][ $sidebar ][ $id ]['settings']['csb_visibility']['conditions'] ) ) {
251
+ foreach ( $data['widgets'][ $sidebar ][ $id ]['settings']['csb_visibility']['conditions'] as $condition_id => $condition_value ) {
252
+ if ( empty( $condition_value ) ) {
253
+
254
+ unset( $data['widgets'][ $sidebar ][ $id ]['settings']['csb_visibility']['conditions'][ $condition_id ] );
255
+
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
261
+ } else {
262
+ $data['widgets'][ $sidebar ] = $widgets;
263
+ }
264
+ }
265
+ return $data;
266
+ }
267
+
268
+ /**
269
+ * Generates the export file and sends it as a download to the browser.
270
+ *
271
+ * @since 2.0
272
+ */
273
+ private function download_export_file() {
274
+ $data = $this->get_export_data();
275
+ $filename = 'sidebars.' . date( 'Y-m-d.H-i-s' ) . '.json';
276
+ $option = defined( 'JSON_PRETTY_PRINT' )? JSON_PRETTY_PRINT : null;
277
+ $content = json_encode( (object) $data, $option );
278
+ // Send the download headers.
279
+ header( 'Pragma: public' );
280
+ header( 'Expires: 0' );
281
+ header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
282
+ header( 'Cache-Control: private', false ); // required for certain browsers
283
+ header( 'Content-type: application/json' );
284
+ header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
285
+ header( 'Content-Transfer-Encoding: binary' );
286
+ header( 'Content-Length: ' . strlen( $content ) );
287
+ // Finally send the export-file content.
288
+ echo '' . $content;
289
+ die();
290
+ }
291
+
292
+ /*=============================*\
293
+ =================================
294
+ == ==
295
+ == PREVIEW ==
296
+ == ==
297
+ =================================
298
+ \*=============================*/
299
+
300
+
301
+ /**
302
+ * Checks if a valid export-file was uploaded and stores the file contents
303
+ * inside self::$import_data. The data is de-serialized.
304
+ * In error case the response object will be set to error status.
305
+ *
306
+ * @since 2.0
307
+ * @param object $req Initial response object for JSON response.
308
+ * @return object Updated response object.
309
+ */
310
+ private function read_import_file( $req ) {
311
+ if ( is_array( $_FILES['data'] ) ) {
312
+ switch ( $_FILES['data']['error'] ) {
313
+ case UPLOAD_ERR_OK:
314
+ // This is the expeted status!
315
+ break;
316
+
317
+ case UPLOAD_ERR_NO_FILE:
318
+ return self::req_err(
319
+ $req,
320
+ __( 'No file was uploaded', 'custom-sidebars' )
321
+ );
322
+
323
+ case UPLOAD_ERR_INI_SIZE:
324
+ case UPLOAD_ERR_FORM_SIZE:
325
+ return self::req_err(
326
+ $req,
327
+ __( 'Import file is too big', 'custom-sidebars' )
328
+ );
329
+
330
+ default:
331
+ return self::req_err(
332
+ $req,
333
+ __( 'Something went wrong', 'custom-sidebars' )
334
+ );
335
+ }
336
+
337
+ $content = file_get_contents( $_FILES['data']['tmp_name'] );
338
+ $data = json_decode( $content, true );
339
+
340
+ if (
341
+ is_array( $data['meta'] ) &&
342
+ is_array( $data['sidebars'] ) &&
343
+ is_array( $data['options'] ) &&
344
+ is_array( $data['widgets'] ) &&
345
+ is_array( $data['categories'] )
346
+ ) {
347
+ $data['meta']['filename'] = $_FILES['data']['name'];
348
+ $data['ignore'] = array();
349
+ self::$import_data = $data;
350
+
351
+ // Remove details that does not exist on current blog.
352
+ $this->prepare_data();
353
+ } else {
354
+ return self::req_err(
355
+ $req,
356
+ __( 'Unexpected import format', 'custom-sidebars' )
357
+ );
358
+ }
359
+ } else {
360
+ return self::req_err(
361
+ $req,
362
+ __( 'No file was uploaded', 'custom-sidebars' )
363
+ );
364
+ }
365
+
366
+ return $req;
367
+ }
368
+
369
+ /**
370
+ * Loads the import-data into the self::$import_data property.
371
+ * The data was prepared by the import-preview screen.
372
+ * Populates the response object.
373
+ *
374
+ * @since 2.0
375
+ * @param object $req Initial response object for JSON response.
376
+ * @return object Updated response object.
377
+ */
378
+ private function prepare_import_data( $req ) {
379
+ $data = json_decode( base64_decode( @$_POST['import_data'] ), true );
380
+
381
+ if (
382
+ is_array( $data['meta'] ) &&
383
+ is_array( $data['sidebars'] ) &&
384
+ is_array( $data['options'] ) &&
385
+ is_array( $data['widgets'] ) &&
386
+ is_array( $data['categories'] )
387
+ ) {
388
+ $data['ignore'] = array();
389
+ self::$import_data = $data;
390
+
391
+ // Remove details that does not exist on current blog.
392
+ $this->prepare_data();
393
+
394
+ // "selected_data" only contains the items that were selected for import.
395
+ $this->selected_data = self::$import_data;
396
+ unset( $this->selected_data['meta'] );
397
+ unset( $this->selected_data['categories'] );
398
+ unset( $this->selected_data['ignore'] );
399
+
400
+ if ( ! isset( $_POST['import_plugin_config'] ) ) {
401
+ unset( $this->selected_data['options'] );
402
+ }
403
+ if ( ! isset( $_POST['import_widgets'] ) ) {
404
+ unset( $this->selected_data['widgets'] );
405
+ } else {
406
+ foreach ( $this->selected_data['widgets'] as $id => $widgets ) {
407
+ $key = 'import_sb_' . $id;
408
+ if ( ! isset( $_POST[ $key ] ) ) {
409
+ unset( $this->selected_data['widgets'][ $id ] );
410
+ }
411
+ }
412
+ }
413
+ foreach ( $this->selected_data['sidebars'] as $id => $sidebar ) {
414
+ $key = 'import_sb_' . $sidebar['id'];
415
+ if ( ! isset( $_POST[ $key ] ) ) {
416
+ unset( $this->selected_data['sidebars'][ $id ] );
417
+ }
418
+ }
419
+
420
+ // Finally: Import the config!
421
+ $req = $this->do_import( $req );
422
+ } else {
423
+ return self::req_err(
424
+ $req,
425
+ __(
426
+ 'Something unexpected happened and we could not finish ' .
427
+ 'the import. Please try again.', 'custom-sidebars'
428
+ )
429
+ );
430
+ }
431
+
432
+ return $req;
433
+ }
434
+
435
+ /**
436
+ * Loops through the import data array and removes configuration which is
437
+ * not relevant for the current blog. I.e. posttypes that are not registered
438
+ * or categories that do not match the current blog.
439
+ *
440
+ * @since 2.0
441
+ */
442
+ private function prepare_data() {
443
+ global $wp_registered_widgets;
444
+ $theme_sidebars = self::get_sidebars();
445
+ $valid_categories = array();
446
+ $valid_sidebars = array();
447
+ $valid_widgets = array();
448
+
449
+ // =====
450
+ // Normalize the sidebar list (change numeric index to sidebar-id).
451
+ $sidebars_remapped = array();
452
+ foreach ( self::$import_data['sidebars'] as $sidebar ) {
453
+ $sidebars_remapped[ $sidebar['id'] ] = $sidebar;
454
+ }
455
+ self::$import_data['sidebars'] = $sidebars_remapped;
456
+
457
+ // =====
458
+ // Get a list of existing/valid sidebar-IDs.
459
+ $valid_sidebars = array_merge(
460
+ array_keys( $theme_sidebars ),
461
+ array_keys( self::$import_data['sidebars'] )
462
+ );
463
+
464
+ // =====
465
+ // Check for theme-sidebars that do not exist.
466
+ foreach ( self::$import_data['options']['modifiable'] as $id => $sb_id ) {
467
+ if ( ! isset( $theme_sidebars[ $sb_id ] ) ) {
468
+ if ( ! isset( self::$import_data['ignore']['sidebars'] ) ) {
469
+ self::$import_data['ignore']['sidebars'] = array();
470
+ }
471
+ self::$import_data['ignore']['sidebars'][] = $sb_id;
472
+ unset( self::$import_data['options']['modifiable'][ $id ] );
473
+ }
474
+ }
475
+
476
+ // =====
477
+ // Remove invalid sidebars from the default replacement options.
478
+ foreach ( array( 'post_type_single', 'post_type_archive', 'category_single', 'category_archive' ) as $key ) {
479
+ foreach ( self::$import_data['options'][ $key ] as $id => $list ) {
480
+ $list = $this->_remove_sidebar_from_list( $list, $valid_sidebars );
481
+ self::$import_data['options'][ $key ][ $id ] = $list;
482
+ }
483
+ }
484
+ foreach ( array( 'blog', 'tags', 'authors', 'search', 'date' ) as $key ) {
485
+ $list = self::$import_data['options'][ $key ];
486
+ $list = $this->_remove_sidebar_from_list( $list, $valid_sidebars );
487
+ self::$import_data['options'][ $key ] = $list;
488
+ }
489
+
490
+ // =====
491
+ // Check for missing/different categories.
492
+ foreach ( get_categories( array( 'hide_empty' => 0 ) ) as $cat ) {
493
+ $valid_categories[ $cat->term_id ] = $cat;
494
+ }
495
+ foreach ( self::$import_data['categories'] as $infos ) {
496
+ $id = $infos['term_id'];
497
+ if (
498
+ empty( $valid_categories[ $id ] ) ||
499
+ $valid_categories[ $id ]->slug != $infos['slug']
500
+ ) {
501
+ if ( ! isset( self::$import_data['ignore']['categories'] ) ) {
502
+ self::$import_data['ignore']['categories'] = array();
503
+ }
504
+ self::$import_data['ignore']['categories'][] = $infos['name'];
505
+ unset( self::$import_data['categories'][ $id ] );
506
+
507
+ // Remove the categories from the config array.
508
+ unset( self::$import_data['options']['category_posts'][ $id ] );
509
+ unset( self::$import_data['options']['category_pages'][ $id ] );
510
+ }
511
+ }
512
+
513
+ // =====
514
+ // Remove missing widgets from import data.
515
+ foreach ( $wp_registered_widgets as $widget ) {
516
+ if ( is_array( $widget['callback'] ) ) {
517
+ $classname = get_class( $widget['callback'][0] );
518
+ } else {
519
+ $classname = $widget['classname'];
520
+ }
521
+ $valid_widgets[ $classname ] = true;
522
+ }
523
+ foreach ( self::$import_data['widgets'] as $sb_id => $sidebar ) {
524
+ if ( ! is_array( $sidebar ) ) { continue; }
525
+ foreach ( $sidebar as $id => $widget_instance ) {
526
+ $version = $widget_instance['version'];
527
+ $instance_class = $widget_instance['classname'];
528
+ $exists = (true === @$valid_widgets[ $instance_class ]);
529
+ if ( ! $exists ) {
530
+ if ( ! isset( self::$import_data['ignore']['widgets'] ) ) {
531
+ self::$import_data['ignore']['widgets'] = array();
532
+ }
533
+ self::$import_data['ignore']['widgets'][] = $widget_instance['name'];
534
+ unset( $sidebar[ $id ] );
535
+ }
536
+ }
537
+ self::$import_data['widgets'][ $sb_id ] = $sidebar;
538
+ }
539
+ }
540
+
541
+ /**
542
+ * Helper function that is used by prepare_data.
543
+ *
544
+ * @since 2.0
545
+ */
546
+ private function _remove_sidebar_from_list( $list, $valid_list ) {
547
+ /**
548
+ * do not process if $list is not an array or is an empty array
549
+ */
550
+ if ( ! is_array( $list ) || empty( $list ) ) {
551
+ return $list;
552
+ }
553
+ foreach ( $list as $id => $value ) {
554
+ if ( ! in_array( $value, $valid_list ) ) {
555
+ unset( $list[ $id ] );
556
+ } else if ( ! in_array( $id, $valid_list ) ) {
557
+ unset( $list[ $id ] );
558
+ }
559
+ }
560
+ return $list;
561
+ }
562
+
563
+ /**
564
+ * Returns the contents of the uploaded import file for preview or import.
565
+ *
566
+ * @since 2.0
567
+ */
568
+ static public function get_import_data() {
569
+ return self::$import_data;
570
+ }
571
+
572
+
573
+ /*============================*\
574
+ ================================
575
+ == ==
576
+ == IMPORT ==
577
+ == ==
578
+ ================================
579
+ \*============================*/
580
+
581
+ /**
582
+ * Process the import data provided in self::$import_data.
583
+ * Save the configuration to database.
584
+ * Populates the response object.
585
+ *
586
+ * @since 2.0
587
+ * @param object $req Initial response object for JSON response.
588
+ * @return object Updated response object.
589
+ */
590
+ private function do_import( $req ) {
591
+ $data = $this->selected_data;
592
+ $msg = array();
593
+
594
+ // =====================================================================
595
+ // Import custom sidebars
596
+
597
+ $sidebars = self::get_custom_sidebars();
598
+ $sidebar_count = 0;
599
+ // First replace existing sidebars.
600
+ foreach ( $sidebars as $idx => $sidebar ) {
601
+ $sb_id = $sidebar['id'];
602
+ if ( isset( $data['sidebars'][ $sb_id ] ) ) {
603
+ $new_sidebar = $data['sidebars'][ $sb_id ];
604
+ $sidebars[ $idx ] = array(
605
+ 'name' => @$new_sidebar['name'],
606
+ 'id' => $sb_id,
607
+ 'description' => @$new_sidebar['description'],
608
+ 'before_widget' => @$new_sidebar['before_widget'],
609
+ 'after_widget' => @$new_sidebar['after_widget'],
610
+ 'before_title' => @$new_sidebar['before_title'],
611
+ 'after_title' => @$new_sidebar['after_title'],
612
+ );
613
+ $sidebar_count += 1;
614
+ unset( $data['sidebars'][ $sb_id ] );
615
+ }
616
+ }
617
+ // Second add new sidebars.
618
+ foreach ( $data['sidebars'] as $sb_id => $new_sidebar ) {
619
+ $sidebars[] = array(
620
+ 'name' => @$new_sidebar['name'],
621
+ 'id' => $sb_id,
622
+ 'description' => @$new_sidebar['description'],
623
+ 'before_widget' => @$new_sidebar['before_widget'],
624
+ 'after_widget' => @$new_sidebar['after_widget'],
625
+ 'before_title' => @$new_sidebar['before_title'],
626
+ 'after_title' => @$new_sidebar['after_title'],
627
+ );
628
+ $sidebar_count += 1;
629
+ }
630
+ if ( $sidebar_count > 0 ) {
631
+ self::set_custom_sidebars( $sidebars );
632
+ $msg[] = sprintf(
633
+ __( 'Imported %d custom sidebar(s)!', 'custom-sidebars' ),
634
+ $sidebar_count
635
+ );
636
+ }
637
+
638
+ // =====================================================================
639
+ // Import plugin settings
640
+ if ( ! empty( $data['options'] ) ) {
641
+ self::set_options( $data['options'] );
642
+ $msg[] = __( 'Plugin options were imported!', 'custom-sidebars' );
643
+ }
644
+
645
+ // =====================================================================
646
+ // Import widgets
647
+ $widget_count = 0;
648
+ $def_sidebars = wp_get_sidebars_widgets();
649
+ $widget_list = array();
650
+ $orig_POST = $_POST;
651
+ // First replace existing sidebars.
652
+ foreach ( $data['widgets'] as $sb_id => $sidebar ) {
653
+ // --- 1. Remove all widgets from the sidebar
654
+
655
+ // @see wp-admin/includes/ajax-actions.php : function wp_ajax_save_widget()
656
+ // Empty the sidebar, in case it contains widgets.
657
+ $old_widgets = @$def_sidebars[ $sb_id ];
658
+ $def_sidebars[ $sb_id ] = array();
659
+ wp_set_sidebars_widgets( $def_sidebars );
660
+
661
+ // Also remove the widget-instances from wp-option table.
662
+ if ( ! is_array( $old_widgets ) ) {
663
+ $old_widgets = array();
664
+ }
665
+ foreach ( $old_widgets as $widget_id ) {
666
+ $id_base = preg_replace( '/-[0-9]+$/', '', $widget_id );
667
+ $_POST = array(
668
+ 'sidebar' => $sb_id,
669
+ 'widget-' . $id_base => array(),
670
+ 'the-widget-id' => $widget_id,
671
+ 'delete_widget' => '1',
672
+ );
673
+ $this->_refresh_widget_settings( $id_base );
674
+ }
675
+
676
+ // --- 2. Import the new widgets to the sidebar
677
+
678
+ foreach ( $sidebar as $class => $widget ) {
679
+ $widget_base = $widget['id_base'];
680
+ $widget_name = $this->_add_new_widget( $widget_base, $widget['settings'] );
681
+
682
+ if ( ! empty( $widget_name ) ) {
683
+ $def_sidebars[ $sb_id ][] = $widget_name;
684
+ $widget_count += 1;
685
+ }
686
+ }
687
+ }
688
+ $_POST = $orig_POST;
689
+ if ( $widget_count > 0 ) {
690
+ wp_set_sidebars_widgets( $def_sidebars );
691
+ $msg[] = sprintf(
692
+ __( 'Imported %d widget(s)!', 'custom-sidebars' ),
693
+ $widget_count
694
+ );
695
+ }
696
+
697
+ $req->message = base64_encode( implode( '<br />', $msg ) );
698
+
699
+ // We return a HTTP header to refresh the widgets page.
700
+ header( 'HTTP/1.1 302 Found' );
701
+ header( 'Location: ' . admin_url( 'widgets.php?cs-msg=' . $req->message ) );
702
+ die();
703
+ }
704
+
705
+ /**
706
+ * Helper function used by the "do_import()" handler.
707
+ * Updates the widget-data in DB.
708
+ *
709
+ * @since 2.0
710
+ */
711
+ private function _refresh_widget_settings( $id_base ) {
712
+ global $wp_registered_widget_updates;
713
+
714
+ foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
715
+
716
+ if ( $name == $id_base ) {
717
+ if ( ! is_callable( $control['callback'] ) ) {
718
+ continue;
719
+ }
720
+
721
+ ob_start();
722
+ if ( is_object( $control['callback'] ) ) {
723
+ $control['callback']->updated = false;
724
+ }
725
+ call_user_func_array( $control['callback'], $control['params'] );
726
+ ob_end_clean();
727
+
728
+ break;
729
+ }
730
+ }
731
+ }
732
+
733
+ /**
734
+ * Helper function used by the "do_import()" handler.
735
+ * Updates the widget-data in DB.
736
+ *
737
+ * @since 2.0
738
+ */
739
+ private function _add_new_widget( $id_base, $instance ) {
740
+ global $wp_registered_widget_updates;
741
+ $widget_name = false;
742
+
743
+ foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
744
+
745
+ if ( $name == $id_base ) {
746
+ if ( ! is_callable( $control['callback'] ) ) {
747
+ continue;
748
+ }
749
+
750
+ if ( is_array( $control['callback'] ) ) {
751
+ $obj = $control['callback'][0];
752
+ } else {
753
+ // We cannot import data from old widgets API.
754
+ break;
755
+ }
756
+ $obj->updated = false;
757
+
758
+ $all_instances = $obj->get_settings();
759
+
760
+ // Find out what the next free number is.
761
+ $new_number = 0;
762
+ foreach ( $all_instances as $number => $data ) {
763
+ $new_number = $number > $new_number ? $number : $new_number;
764
+ }
765
+ $new_number += 1;
766
+ $widget_name = $id_base . '-' . $new_number;
767
+ /**
768
+ * reset previous data
769
+ */
770
+ $keys = array( 'title', 'text', 'filter', 'csb_visibility', 'csb_clone' );
771
+ foreach ( $keys as $key ) {
772
+ if ( isset( $_POST[ $key ] ) ) {
773
+ unset( $_POST[ $key ] );
774
+ }
775
+ }
776
+ /**
777
+ * set current values
778
+ */
779
+ foreach ( $instance as $key => $value ) {
780
+ $_POST[ $key ] = $value;
781
+ }
782
+
783
+ /**
784
+ * Filter a widget's settings before saving.
785
+ *
786
+ * Returning false will effectively short-circuit the widget's ability
787
+ * to update settings.
788
+ *
789
+ * @see wp-includes/widgets.php : function "update_callback()"
790
+ * @since WordPress 2.8.0
791
+ *
792
+ * @param array $instance The current widget instance's settings.
793
+ * @param array $new_instance Array of new widget settings.
794
+ * @param array $old_instance Array of old widget settings.
795
+ * @param WP_Widget $this The current widget instance.
796
+ */
797
+ $instance = apply_filters( 'widget_update_callback', $instance, $instance, array(), $obj );
798
+ if ( false !== $instance ) {
799
+ $all_instances[ $new_number ] = $instance;
800
+ }
801
+
802
+ $obj->save_settings( $all_instances );
803
+
804
+ break;
805
+ }
806
+ }
807
+
808
+ return $widget_name;
809
+ }
810
+ };
inc/class-custom-sidebars-replacer.php CHANGED
@@ -37,7 +37,11 @@ class CustomSidebarsReplacer extends CustomSidebars {
37
  array( $this, 'register_custom_sidebars' )
38
  );
39
 
40
-
 
 
 
 
41
 
42
  if ( ! is_admin() ) {
43
  // Frontend hooks.
@@ -495,7 +499,17 @@ class CustomSidebarsReplacer extends CustomSidebars {
495
  $current_author = $author_object->ID;
496
  $expl && do_action( 'cs_explain', 'Type 9: Author Archive (' . $current_author . ')' );
497
 
498
-
 
 
 
 
 
 
 
 
 
 
499
 
500
  // 9.2 Then check if there is an "Any authors" sidebar
501
  if ( $replacements_todo > 0 ) {
@@ -659,5 +673,22 @@ class CustomSidebarsReplacer extends CustomSidebars {
659
  return $sidebar;
660
  }
661
 
662
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
663
  };
37
  array( $this, 'register_custom_sidebars' )
38
  );
39
 
40
+ // Support translation via WPML plugin.
41
+ add_action(
42
+ 'register_sidebar',
43
+ array( $this, 'translate_sidebar' )
44
+ );
45
 
46
  if ( ! is_admin() ) {
47
  // Frontend hooks.
499
  $current_author = $author_object->ID;
500
  $expl && do_action( 'cs_explain', 'Type 9: Author Archive (' . $current_author . ')' );
501
 
502
+ // 9.1 First check for specific authors.
503
+ foreach ( $sidebars as $sb_id ) {
504
+ if ( ! empty( $options['author_archive'][ $current_author ][ $sb_id ] ) ) {
505
+ $replacements[ $sb_id ] = array(
506
+ $options['author_archive'][ $current_author ][ $sb_id ],
507
+ 'author_archive',
508
+ $current_author,
509
+ );
510
+ $replacements_todo -= 1;
511
+ }
512
+ }
513
 
514
  // 9.2 Then check if there is an "Any authors" sidebar
515
  if ( $replacements_todo > 0 ) {
673
  return $sidebar;
674
  }
675
 
676
+ /**
677
+ * Translates a sidebar using WPML right after it was registered.
678
+ *
679
+ * @since 2.0.9.7
680
+ * @param array $sidebar The sidebar that was registered
681
+ */
682
+ public function translate_sidebar( $sidebar ) {
683
+ if ( ! function_exists( 'icl_t' ) ) { return false; }
684
+
685
+ global $wp_registered_sidebars;
686
+ $context = 'Sidebar';
687
+
688
+ // Translate the name and description.
689
+ $sidebar['name'] = icl_t( $context, $sidebar['id'] . '-name', $sidebar['name'] );
690
+ $sidebar['description'] = icl_t( $context, $sidebar['id'] . '-description', $sidebar['description'] );
691
+
692
+ $wp_registered_sidebars[ $sidebar['id'] ] = $sidebar;
693
+ }
694
  };
inc/class-custom-sidebars-visibility.php ADDED
@@ -0,0 +1,1025 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_action( 'cs_init', array( 'CustomSidebarsVisibility', 'instance' ) );
4
+
5
+ /**
6
+ * Adds visibility options to all widgets: Hide or show widgets only when
7
+ * specific conditions are met.
8
+ *
9
+ * @since 2.0
10
+ */
11
+ class CustomSidebarsVisibility extends CustomSidebars {
12
+
13
+ public static $filtered_tax_list = false;
14
+ /**
15
+ * Returns the singleton object.
16
+ *
17
+ * @since 2.0
18
+ */
19
+ public static function instance() {
20
+ static $Inst = null;
21
+
22
+ if ( null === $Inst ) {
23
+ $Inst = new CustomSidebarsVisibility();
24
+ }
25
+
26
+ return $Inst;
27
+ }
28
+
29
+ /**
30
+ * Constructor is private -> singleton.
31
+ *
32
+ * @since 2.0
33
+ */
34
+ private function __construct() {
35
+ if ( is_admin() ) {
36
+ // in_widget_form: Add our button inside each widget.
37
+ add_action(
38
+ 'in_widget_form',
39
+ array( $this, 'admin_widget_button' ),
40
+ 10, 3
41
+ );
42
+
43
+ // When the widget is saved (via Ajax) we save our options.
44
+ add_filter(
45
+ 'widget_update_callback',
46
+ array( $this, 'admin_widget_update' ),
47
+ 10, 3
48
+ );
49
+
50
+ lib3()->ui->add( CSB_JS_URL . 'cs-visibility.min.js', 'widgets.php' );
51
+ lib3()->ui->add( CSB_CSS_URL . 'cs-visibility.css', 'widgets.php' );
52
+
53
+ // Custom Sidebars Ajax request.
54
+ add_action(
55
+ 'cs_ajax_request_get',
56
+ array( $this, 'handle_ajax' )
57
+ );
58
+ } else {
59
+ // Filters the list of widget-areas and their widgets
60
+ add_filter(
61
+ 'sidebars_widgets',
62
+ array( $this, 'sidebars_widgets' )
63
+ );
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Extracts and sanitizes the CSB visibility data from the widget instance.
69
+ *
70
+ * @since 2.0
71
+ * @param array $instance The widget instance data.
72
+ * @return array Sanitized CSB visibility data.
73
+ */
74
+ protected function get_widget_data( $instance ) {
75
+ static $Condition_keys = null;
76
+ $data = array();
77
+
78
+ if ( null === $Condition_keys ) {
79
+ $tax_list = get_taxonomies( array( 'public' => true ), 'objects' );
80
+ $type_list = CustomSidebars::get_post_types( 'objects' );
81
+ $Condition_keys = array(
82
+ 'guest' => array(),
83
+ 'date' => array(),
84
+ 'roles' => array(),
85
+ 'pagetypes' => array(),
86
+ 'posttypes' => array(),
87
+ 'membership' => array(),
88
+ 'membership2' => array(),
89
+ 'prosite' => array(),
90
+ );
91
+ foreach ( $type_list as $type_item ) {
92
+ $Condition_keys[ 'pt-' . $type_item->name ] = array();
93
+ }
94
+ foreach ( $tax_list as $tax_item ) {
95
+ $Condition_keys[ 'tax-' . $tax_item->name ] = array();
96
+ }
97
+ }
98
+
99
+ if ( isset( $instance['csb_visibility'] ) ) {
100
+ $data = $instance['csb_visibility'];
101
+ }
102
+
103
+ $valid_action = array( 'show', 'hide' );
104
+ if ( ! isset( $data['action'] ) || ! in_array( $data['action'], $valid_action ) ) {
105
+ $data['action'] = reset( $valid_action );
106
+ }
107
+
108
+ $conditions = isset( $data['conditions'] )? $data['conditions'] : array();
109
+ if ( ! is_array( $conditions ) ) {
110
+ $conditions = array();
111
+ }
112
+ $data['conditions'] = array();
113
+
114
+ $data['always'] = true;
115
+ foreach ( $Condition_keys as $key => $def_value ) {
116
+ $val = $def_value;
117
+ if ( isset( $conditions[ $key ] ) && ! empty( $conditions[ $key ] ) ) {
118
+ $data['always'] = false;
119
+ $val = $conditions[ $key ];
120
+ }
121
+ $data['conditions'][ $key ] = $val;
122
+ }
123
+
124
+ return $data;
125
+ }
126
+
127
+ /**
128
+ * Action handler for 'in_widget_form'
129
+ *
130
+ * @since 2.0
131
+ */
132
+ public function admin_widget_button( $widget, $return, $instance ) {
133
+ static $Loaded = false;
134
+ static $tax_list = array();
135
+ static $type_list = array();
136
+ static $role_list = array();
137
+ static $membership_levels = array();
138
+ static $pagetype_list = array();
139
+
140
+ if ( false === $Loaded ) {
141
+ $tax_list = get_taxonomies( array( 'public' => true ), 'objects' );
142
+ $type_list = CustomSidebars::get_post_types( 'objects' );
143
+ $role_list = array_reverse( get_editable_roles() );
144
+ $membership_levels = $this->get_membership_levels();
145
+ $membership2_items = $this->get_membership2_items();
146
+ $pagetype_list = array(
147
+ 'frontpage' => 'Front Page',
148
+ 'home' => 'Post Index',
149
+ 'single' => 'Single page',
150
+ //'posts' => 'Posts page', "Posts page" is same as "Post Index"...
151
+ 'archive' => 'Archives',
152
+ 'search' => 'Search results',
153
+ 'e404' => 'Not found (404)',
154
+ 'preview' => 'Preview',
155
+ 'day' => 'Archive: Day',
156
+ 'month' => 'Archive: Month',
157
+ 'year' => 'Archive: Year',
158
+ );
159
+
160
+ // Remove taxonomies without values.
161
+ if ( ! self::$filtered_tax_list ) {
162
+ foreach ( $tax_list as $index => $tax_item ) {
163
+ $tags = get_terms( $tax_item->name, array( 'hide_empty' => false ) );
164
+ if ( empty( $tags ) ) {
165
+ unset( $tax_list[ $index ] );
166
+ }
167
+ }
168
+ self::$filtered_tax_list = $tax_list;
169
+ } else {
170
+ $tax_list = self::$filtered_tax_list;
171
+ }
172
+ }
173
+
174
+ $is_visible = ( isset( $_POST['csb_visible'] ) && '1' == $_POST['csb_visible'] ? 1 : 0);
175
+ $data = $this->get_widget_data( $instance );
176
+ $action_show = ('show' == $data['action']);
177
+ $cond = $data['conditions'];
178
+
179
+ ?>
180
+ <div class="csb-visibility csb-visibility-<?php echo esc_attr( $widget->id ); ?>"
181
+ data-widget="<?php echo esc_attr( $widget->option_name ); ?>"
182
+ data-number="<?php echo esc_attr( absint( @$widget->number ) ); ?>">
183
+ <?php
184
+ /*
185
+ * This input is only used to determine if the "visibility" button
186
+ * should be displayed in the widget form.
187
+ */
188
+ ?>
189
+ <input type="hidden" name="csb-visibility-button" value="0" />
190
+ <?php if ( ! isset( $_POST['csb-visibility-button'] ) ) : ?>
191
+ <a href="#" class="button csb-visibility-button"><span class="dashicons dashicons-visibility"></span> <?php _e( 'Visibility', 'custom-sidebars' ); ?></a>
192
+ <?php else : ?>
193
+ <script>jQuery(function() { jQuery('.csb-visibility-<?php echo esc_js( $widget->id ); ?>').closest('.widget').trigger('csb:update'); }); </script>
194
+ <?php endif; ?>
195
+
196
+ <div class="csb-visibility-inner" <?php if ( ! $is_visible ) : ?>style="display:none"<?php endif; ?>>
197
+ <input type="hidden" name="csb_visible" class="csb-visible-flag" value="<?php echo esc_attr( $is_visible ); ?>" />
198
+
199
+ <div class="csb-option-row csb-action">
200
+ <label for="<?php echo esc_attr( $widget->id ); ?>-action" class="lbl-show-if toggle-action" <?php if ( ! $action_show ) : ?>style="display:none"<?php endif; ?>><?php _e( '<b>Show</b> widget if:', 'custom-sidebars' ); ?></label>
201
+ <label for="<?php echo esc_attr( $widget->id ); ?>-action" class="lbl-hide-if toggle-action" <?php if ( $action_show ) : ?>style="display:none"<?php endif; ?>><?php _e( '<b>Hide</b> widget if:', 'custom-sidebars' ); ?></label>
202
+ <input type="hidden" id="<?php echo esc_attr( $widget->id ); ?>-action" name="csb_visibility[action]" value="<?php echo esc_attr( $data['action'] ); ?>" />
203
+ <i class="dashicons dashicons-plus choose-filters show-on-hover action"></i>
204
+ <ul class="dropdown" style="display:none">
205
+ <li class="csb-group"><?php _e( 'Filters', 'custom-sidebars' ); ?></li>
206
+ <li class="add-filter"
207
+ data-for=".csb-date"
208
+ style="display:none">
209
+ <?php _e( 'Date', 'custom-sidebars' ); ?>
210
+ </li>
211
+ <li class="add-filter"
212
+ data-for=".csb-guest"
213
+ <?php if ( ! empty( $cond['guest'] ) ) : ?>style="display:none"<?php endif; ?>>
214
+ <?php _e( 'Guests', 'custom-sidebars' ); ?>
215
+ </li>
216
+ <li class="add-filter"
217
+ data-for=".csb-roles"
218
+ <?php if ( ! empty( $cond['roles'] ) ) : ?>style="display:none"<?php endif; ?>>
219
+ <?php _e( 'Roles', 'custom-sidebars' ); ?>
220
+ </li>
221
+ <?php if ( false != $membership_levels ) : ?>
222
+ <li class="add-filter"
223
+ data-for=".csb-membership">
224
+ <?php _e( 'Membership', 'custom-sidebars' ); ?>
225
+ </li>
226
+ <?php endif; ?>
227
+ <?php if ( false != $membership2_items ) : ?>
228
+ <li class="add-filter"
229
+ data-for=".csb-membership2">
230
+ <?php _e( 'Membership2', 'custom-sidebars' ); ?>
231
+ </li>
232
+ <?php endif; ?>
233
+ <li class="add-filter"
234
+ data-for=".csb-pagetypes"
235
+ <?php if ( ! empty( $cond['pagetypes'] ) ) : ?>style="display:none"<?php endif; ?>>
236
+ <?php _e( 'Special pages', 'custom-sidebars' ); ?>
237
+ </li>
238
+ <li class="add-filter"
239
+ data-for=".csb-posttypes"
240
+ <?php if ( ! empty( $cond['posttypes'] ) ) : ?>style="display:none"<?php endif; ?>>
241
+ <?php _e( 'For posttype', 'custom-sidebars' ); ?>
242
+ </li>
243
+ <li class="csb-group"><?php _e( 'Taxonomy', 'custom-sidebars' ); ?></li>
244
+ <?php foreach ( $tax_list as $tax_item ) :
245
+ $row_id = 'tax-' . $tax_item->name;
246
+ ?>
247
+ <li class="add-filter"
248
+ data-for=".csb-<?php echo esc_attr( $row_id ); ?>"
249
+ <?php if ( ! empty( $cond[ $row_id ] ) ) : ?>style="display:none"<?php endif; ?>>
250
+ <?php echo esc_html( $tax_item->labels->name ); ?>
251
+ </li>
252
+ <?php
253
+ endforeach; ?>
254
+ </ul>
255
+ </div>
256
+
257
+ <?php $block_name = 'csb_visibility[conditions]'; ?>
258
+
259
+ <div class="csb-option-row csb-always" <?php if ( ! $data['always'] ) : ?>style="display:none"<?php endif; ?>>
260
+ <label><?php _e( 'Always', 'custom-sidebars' ); ?></label>
261
+ </div>
262
+
263
+ <?php /* DATE */ /* ?>
264
+ <div class="csb-option-row csb-date" style="display:none">
265
+ <label for="<?php echo esc_attr( $widget->id ); ?>-date">
266
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
267
+ <?php _e( 'On these dates', 'custom-sidebars' ); ?>
268
+ </label>
269
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
270
+ <input type="text"
271
+ id="<?php echo esc_attr( $widget->id ); ?>-date"
272
+ name="<?php echo esc_attr( $block_name ); ?>[date][from]"
273
+ value="<?php echo esc_attr( @$cond['date']['from'] ); ?>" />
274
+ <input type="text"
275
+ id="<?php echo esc_attr( $widget->id ); ?>-date-to"
276
+ name="<?php echo esc_attr( $block_name ); ?>[date][to]"
277
+ value="<?php echo esc_attr( @$cond['date']['to'] ); ?>" />
278
+ </div>
279
+ <?php */ ?>
280
+
281
+ <?php /* GUEST */ ?>
282
+ <div class="csb-option-row csb-guest" <?php if ( empty( $cond['guest'] ) ) : ?>style="display:none"<?php endif; ?>>
283
+ <label for="<?php echo esc_attr( $widget->id ); ?>-guest1" style="padding-top:10px;margin-bottom:0">
284
+ <input id="<?php echo esc_attr( $widget->id ); ?>-guest1" type="radio" name="<?php echo esc_attr( $block_name ); ?>[guest][]" value="guest" <?php checked( in_array( 'guest', $cond['guest'] ) ); ?> />
285
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
286
+ <?php _e( 'User is not logged-in (Guest)', 'custom-sidebars' ); ?><br />
287
+ </label>
288
+ <label for="<?php echo esc_attr( $widget->id ); ?>-guest2" style="border:0;margin-bottom:0">
289
+ <input id="<?php echo esc_attr( $widget->id ); ?>-guest2" type="radio" name="<?php echo esc_attr( $block_name ); ?>[guest][]" value="member" <?php checked( in_array( 'member', $cond['guest'] ) ); ?> />
290
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
291
+ <?php _e( 'User is logged-in (Member)', 'custom-sidebars' ); ?>
292
+ </label>
293
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
294
+ </div>
295
+
296
+ <?php /* ROLES */ ?>
297
+ <div class="csb-option-row csb-roles" <?php if ( empty( $cond['roles'] ) ) : ?>style="display:none"<?php endif; ?>>
298
+ <label for="<?php echo esc_attr( $widget->id ); ?>-roles">
299
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
300
+ <?php _e( 'User has role', 'custom-sidebars' ); ?>
301
+ </label>
302
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
303
+ <select id="<?php echo esc_attr( $widget->id ); ?>-roles" name="<?php echo esc_attr( $block_name ); ?>[roles][]" multiple="multiple">
304
+ <?php foreach ( $role_list as $role => $details ) : ?>
305
+ <?php $name = translate_user_role( $details['name'] ); ?>
306
+ <?php $is_selected = in_array( $role, $cond['roles'] ); ?>
307
+ <option <?php selected( $is_selected, true ); ?> value="<?php echo esc_attr( $role ); ?>">
308
+ <?php echo esc_html( $name ); ?>
309
+ </option>
310
+ <?php endforeach; ?>
311
+ </select>
312
+ </div>
313
+
314
+ <?php /* MEMBERSHIP */ ?>
315
+ <?php if ( is_array( $membership_levels ) ) : ?>
316
+ <div class="csb-option-row csb-membership" <?php if ( empty( $cond['membership'] ) ) : ?>style="display:none"<?php endif; ?>>
317
+ <label for="<?php echo esc_attr( $widget->id ); ?>-membership">
318
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
319
+ <?php _e( 'User has Membership Level', 'custom-sidebars' ); ?>
320
+ </label>
321
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
322
+ <select id="<?php echo esc_attr( $widget->id ); ?>-membership" name="<?php echo esc_attr( $block_name ); ?>[membership][]" multiple="multiple">
323
+ <?php foreach ( $membership_levels as $level ) : ?>
324
+ <?php $is_selected = in_array( $level['id'], $cond['membership'] ); ?>
325
+ <option <?php selected( $is_selected ); ?> value="<?php echo esc_attr( $level['id'] ); ?>">
326
+ <?php echo esc_html( $level['level_title'] ); ?>
327
+ <?php if ( ! $level['level_active'] ) { _e( '(inactive)', 'custom-sidebars' ); } ?>
328
+ </option>
329
+ <?php endforeach; ?>
330
+ </select>
331
+ </div>
332
+ <?php endif; ?>
333
+
334
+ <?php /* MEMBERSHIP2 (PROTECTED CONTENT) */ ?>
335
+ <?php if ( is_array( $membership2_items ) ) : ?>
336
+ <div class="csb-option-row csb-membership2" <?php if ( empty( $cond['membership2'] ) ) : ?>style="display:none"<?php endif; ?>>
337
+ <label for="<?php echo esc_attr( $widget->id ); ?>-membership2">
338
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
339
+ <?php _e( 'User has Membership', 'custom-sidebars' ); ?>
340
+ </label>
341
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
342
+ <select id="<?php echo esc_attr( $widget->id ); ?>-membership2" name="<?php echo esc_attr( $block_name ); ?>[membership2][]" multiple="multiple">
343
+ <?php foreach ( $membership2_items as $item ) : ?>
344
+ <?php $is_selected = in_array( $item->id, $cond['membership2'] ); ?>
345
+ <option <?php selected( $is_selected ); ?> value="<?php echo esc_attr( $item->id ); ?>">
346
+ <?php echo esc_html( $item->name ); ?>
347
+ <?php if ( ! $item->active ) { _e( '(inactive)', 'custom-sidebars' ); } ?>
348
+ </option>
349
+ <?php endforeach; ?>
350
+ </select>
351
+ </div>
352
+ <?php endif; ?>
353
+
354
+ <?php /* PAGE TYPES */ ?>
355
+ <div class="csb-option-row csb-pagetypes" <?php if ( empty( $cond['pagetypes'] ) ) : ?>style="display:none"<?php endif; ?>>
356
+ <label for="<?php echo esc_attr( $widget->id ); ?>-pagetypes">
357
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
358
+ <?php _e( 'On these special pages', 'custom-sidebars' ); ?>
359
+ </label>
360
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
361
+ <select id="<?php echo esc_attr( $widget->id ); ?>-pagetypes" name="<?php echo esc_attr( $block_name ); ?>[pagetypes][]" multiple="multiple">
362
+ <?php foreach ( $pagetype_list as $type => $name ) : ?>
363
+ <?php $is_selected = in_array( $type, $cond['pagetypes'] ); ?>
364
+ <option <?php selected( $is_selected ); ?> value="<?php echo esc_attr( $type ); ?>">
365
+ <?php echo esc_html( $name ); ?>
366
+ </option>
367
+ <?php endforeach; ?>
368
+ </select>
369
+ </div>
370
+
371
+ <?php /* POSTTYPES */ ?>
372
+ <div class="csb-option-row csb-posttypes"
373
+ <?php if ( empty( $cond['posttypes'] ) ) : ?>style="display:none"<?php endif; ?>>
374
+
375
+ <label for="<?php echo esc_attr( $widget->id ); ?>-posttypes">
376
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
377
+ <?php _e( 'On any page of these types', 'custom-sidebars' ); ?>
378
+ </label>
379
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
380
+ <select class="posttype"
381
+ id="<?php echo esc_attr( $widget->id ); ?>-posttypes"
382
+ name="<?php echo esc_attr( $block_name ); ?>[posttypes][]"
383
+ multiple="multiple">
384
+ <?php foreach ( $type_list as $type_item ) : ?>
385
+ <?php $is_selected = in_array( $type_item->name, $cond['posttypes'] ); ?>
386
+ <option <?php selected( $is_selected ); ?> value="<?php echo esc_attr( $type_item->name ); ?>">
387
+ <?php echo esc_html( $type_item->labels->name ); ?>
388
+ </option>
389
+ <?php endforeach; ?>
390
+ </select>
391
+
392
+ <?php /* SPECIFIC POSTS */ ?>
393
+ <?php foreach ( $type_list as $type_item ) :
394
+ $row_id = 'pt-' . $type_item->name;
395
+ $lbl_all = sprintf( __( 'Only for specific %s', 'custom-sidebars' ), $type_item->labels->name );
396
+ $lbl_single = sprintf( __( 'Only these %s:', 'custom-sidebars' ), $type_item->labels->name );
397
+ $is_selected = in_array( $type_item->name, $cond['posttypes'] );
398
+ $ajax_url = admin_url( 'admin-ajax.php?action=cs-ajax&do=visibility&posttype=' . $type_item->name );
399
+ $sel = array();
400
+
401
+ if ( ! empty( $cond[ $row_id ] ) ) {
402
+ $posts = get_posts(
403
+ array(
404
+ 'post_type' => $type_item->name,
405
+ 'order_by' => 'title',
406
+ 'order' => 'ASC',
407
+ 'numberposts' => '0',
408
+ 'include' => implode( ',', $cond[ $row_id ] ),
409
+ )
410
+ );
411
+
412
+ foreach ( $posts as $post ) {
413
+ $sel[] = $post->ID . '::' . str_replace( '::', ':', $post->post_title );
414
+ }
415
+ }
416
+ ?>
417
+ <div class="csb-detail-row csb-<?php echo esc_attr( $row_id ); ?>"
418
+ <?php if ( ! $is_selected ) : ?>style="display:none"<?php endif; ?>>
419
+
420
+ <label for="<?php echo esc_attr( $widget->id ); ?>-<?php echo esc_attr( $row_id ); ?>">
421
+ <input type="checkbox"
422
+ id="<?php echo esc_attr( $widget->id ); ?>-<?php echo esc_attr( $row_id ); ?>"
423
+ <?php checked( ! empty( $cond[ $row_id ] ) ); ?>
424
+ data-lbl-all="<?php echo esc_attr( $lbl_all ); ?>"
425
+ data-lbl-single="<?php echo esc_attr( $lbl_single ); ?>" />
426
+ <span class="lbl">
427
+ <?php echo esc_html( empty( $cond[ $row_id ] ) ? $lbl_all : $lbl_single ); ?>
428
+ </span>
429
+ </label>
430
+ <div class="detail" <?php if ( empty( $cond[ $row_id ] ) ) : ?>style="display:none"<?php endif; ?>>
431
+
432
+ <input type="hidden"
433
+ name="<?php echo esc_attr( $block_name ); ?>[<?php echo esc_attr( $row_id ); ?>]"
434
+ value="<?php echo esc_attr( implode( ',', $sel ) ); ?>"
435
+ data-select-ajax="<?php echo esc_url( $ajax_url ); ?>" />
436
+ </div>
437
+ </div>
438
+ <?php endforeach; ?>
439
+ </div>
440
+
441
+ <?php /* SPECIFIC TAXONOMY */ ?>
442
+ <?php
443
+ foreach ( $tax_list as $tax_item ) {
444
+
445
+ $row_id = 'tax-' . $tax_item->name;
446
+ $ajax_url = admin_url( 'admin-ajax.php?action=cs-ajax&do=visibility&tag=' . $tax_item->name );
447
+ $sel = array();
448
+
449
+ if ( ! empty( $cond[ $row_id ] ) ) {
450
+ $tags = get_terms(
451
+ $tax_item->name,
452
+ array(
453
+ 'include' => implode( ',', $cond[ $row_id ] ),
454
+ 'hide_empty' => false,
455
+ )
456
+ );
457
+
458
+ foreach ( $tags as $tag ) {
459
+ $sel[] = $tag->term_id . '::' . str_replace( '::', ':', $tag->name );
460
+ }
461
+ }
462
+
463
+ ?>
464
+ <div class="csb-option-row csb-<?php echo esc_attr( $row_id ); ?>"
465
+ <?php if ( empty( $cond[ $row_id ] ) ) : ?>style="display:none"<?php endif; ?>>
466
+
467
+ <label for="<?php echo esc_attr( $widget->id ); ?>-<?php echo esc_attr( $row_id ); ?>">
468
+ <span class="csb-and" style="display:none"><?php _e( 'AND', 'custom-sidebars' ); ?></span>
469
+ <?php echo esc_html( $tax_item->labels->name ); ?>
470
+ </label>
471
+ <i class="dashicons dashicons-trash clear-filter show-on-hover action"></i>
472
+ <select
473
+ id="<?php echo esc_attr( $widget->id ); ?>-<?php echo esc_attr( $row_id ); ?>"
474
+ name="<?php echo esc_attr( $block_name ); ?>[<?php echo esc_attr( $row_id ); ?>][]"
475
+ multiple="multiple"
476
+ >
477
+ <?php
478
+ $terms = get_terms( $tax_item->name );
479
+ foreach ( $terms as $item ) {
480
+ ?>
481
+ <?php $is_selected = in_array( $item->term_id, $sel ); ?>
482
+ <option <?php selected( $is_selected ); ?> value="<?php echo esc_attr( $item->term_id ); ?>">
483
+ <?php echo esc_html( $item->name ); ?>
484
+ </option>
485
+ <?php } ?>
486
+ </select>
487
+ </div>
488
+ <?php
489
+ }
490
+ ?>
491
+
492
+ </div>
493
+ </div>
494
+ <?php
495
+ }
496
+
497
+ /**
498
+ * Integration with the WPMU Dev Membership plugin:
499
+ * If the plugin is installed and active this function returns a list of
500
+ * all membership levels.
501
+ *
502
+ * If the plugin is not active the return value is boolean false.
503
+ *
504
+ * @since 2.0
505
+ * @return bool|array
506
+ */
507
+ public function get_membership_levels() {
508
+ $Result = null;
509
+
510
+ if ( null === $Result ) {
511
+ if (
512
+ function_exists( 'M_get_membership_active' ) &&
513
+ 'no' != M_get_membership_active() &&
514
+ defined( 'MEMBERSHIP_TABLE_LEVELS' )
515
+ ) {
516
+ global $wpdb;
517
+ $Result = $wpdb->get_results(
518
+ sprintf(
519
+ 'SELECT
520
+ id, level_title, level_active
521
+ FROM %s
522
+ ORDER BY id',
523
+ MEMBERSHIP_TABLE_LEVELS
524
+ ), ARRAY_A
525
+ );
526
+ } else {
527
+ $Result = false;
528
+ }
529
+ }
530
+
531
+ return $Result;
532
+ }
533
+
534
+ /**
535
+ * Integration with the WPMU Dev Membership2 plugin:
536
+ * If the plugin is installed and active this function returns a list of
537
+ * all membership levels.
538
+ *
539
+ * If the plugin is not active the return value is boolean false.
540
+ *
541
+ * @since 2.0
542
+ * @return bool|array
543
+ */
544
+ public function get_membership2_items() {
545
+ $Result = null;
546
+
547
+ if ( null === $Result ) {
548
+ $is_active_membership = apply_filters( 'ms_active', false );
549
+ if ( $is_active_membership ) {
550
+ $Result = MS_Plugin::$api->list_memberships( true );
551
+ }
552
+ }
553
+
554
+ return $Result;
555
+ }
556
+
557
+ /**
558
+ * When user saves the widget we check for the
559
+ *
560
+ * @since 2.0
561
+ * @param array $new_instance New settings for this instance as input by the user.
562
+ * @param array $old_instance Old settings for this instance.
563
+ * @return array Modified settings.
564
+ */
565
+ public function admin_widget_update( $instance, $new_instance, $old_instance ) {
566
+ $data = $this->get_widget_data( $_POST );
567
+
568
+ foreach ( $data['conditions'] as $key => $list ) {
569
+ if ( ! is_array( $list ) ) {
570
+ $list = explode( ',', $list );
571
+ $data['conditions'][ $key ] = $list;
572
+ }
573
+ }
574
+ $instance['csb_visibility'] = $data;
575
+
576
+ return $instance;
577
+ }
578
+
579
+ // == Front-end functions
580
+
581
+ /**
582
+ * Filter the list of widgets for a sidebar so that active sidebars work as expected.
583
+ *
584
+ * @since 2.0
585
+ * @param array $widget_areas An array of widget areas and their widgets.
586
+ * @return array The modified $widget_area array.
587
+ */
588
+ public function sidebars_widgets( $widget_areas ) {
589
+ static $Settings = array();
590
+ static $Result = array();
591
+
592
+ $expl = CustomSidebarsExplain::do_explain();
593
+
594
+ if ( ! did_action( 'cs_before_replace_sidebars' ) ) {
595
+ return $widget_areas;
596
+ }
597
+
598
+ $key = serialize( $widget_areas );
599
+
600
+ if ( ! isset( $Result[ $key ] ) ) {
601
+ $expl && do_action( 'cs_explain', '<h4>Filter widgets</h4>', true );
602
+ foreach ( $widget_areas as $widget_area => $widgets ) {
603
+ if ( empty( $widgets ) ) {
604
+ continue;
605
+ }
606
+
607
+ if ( 'wp_inactive_widgets' == $widget_area ) {
608
+ continue;
609
+ }
610
+
611
+ $expl && do_action( 'cs_explain', '<h5>Sidebar "' . $widget_area . '"</h5>', true );
612
+
613
+ foreach ( $widgets as $position => $widget_id ) {
614
+ // Find the conditions for this widget.
615
+ if ( preg_match( '/^(.+?)-(\d+)$/', $widget_id, $matches ) ) {
616
+ $id_base = $matches[1];
617
+ $widget_number = intval( $matches[2] );
618
+ } else {
619
+ $id_base = $widget_id;
620
+ $widget_number = null;
621
+ }
622
+
623
+ if ( ! isset( $Settings[ $id_base ] ) ) {
624
+ $Settings[ $id_base ] = get_option( 'widget_' . $id_base );
625
+ }
626
+
627
+ $expl && do_action( 'cs_explain', 'Widget "' . $widget_id . '"', true );
628
+
629
+ // New multi widget (WP_Widget)
630
+ if ( ! is_null( $widget_number ) ) {
631
+ if ( isset( $Settings[ $id_base ][ $widget_number ] ) && false === $this->maybe_display_widget( $Settings[ $id_base ][ $widget_number ] ) ) {
632
+ unset( $widget_areas[ $widget_area ][ $position ] );
633
+ }
634
+ } elseif ( ! empty( $Settings[ $id_base ] ) && false === $this->maybe_display_widget( $Settings[ $id_base ] ) ) {
635
+ // Old single widget.
636
+ unset( $widget_areas[ $widget_area ][ $position ] );
637
+ }
638
+ }
639
+ }
640
+
641
+ $Result[ $key ] = $widget_areas;
642
+ }
643
+
644
+ return $Result[ $key ];
645
+ }
646
+
647
+ public function maybe_display_widget( $instance ) {
648
+ global $post, $wp_query;
649
+ static $Type_list = null;
650
+ static $Tax_list = null;
651
+
652
+ $show_widget = true;
653
+ $condition_true = true;
654
+ $action = 'show';
655
+ $explain = ''; // This is used to explain why a widget is not displayed.
656
+ $expl = CustomSidebarsExplain::do_explain();
657
+
658
+ if ( empty( $instance['csb_visibility'] ) || empty( $instance['csb_visibility']['conditions'] ) ) {
659
+ return $show_widget;
660
+ }
661
+
662
+ $cond = $instance['csb_visibility']['conditions'];
663
+ $action = 'hide' != $instance['csb_visibility']['action'] ? 'show' : 'hide';
664
+
665
+ if ( $instance['csb_visibility']['always'] ) {
666
+ $expl && do_action( 'cs_explain', '<span style="color:#090">Always</span> <b>' . $action . '</b>' );
667
+ return ( 'hide' == $action ? false : true );
668
+ }
669
+
670
+ if ( null === $Type_list ) {
671
+ $Tax_list = get_taxonomies( array( 'public' => true ), 'objects' );
672
+ $Type_list = get_post_types( array( 'public' => true ), 'objects' );
673
+ }
674
+
675
+ // Filter for DATE-RANGE.
676
+ if ( $condition_true && ! empty( $cond['date'] ) ) {
677
+ // not implemented yet...
678
+ }
679
+
680
+ // Filter for GUEST STATUS.
681
+ if ( $condition_true && ! empty( $cond['guest'] ) && is_array( $cond['guest'] ) ) {
682
+ $expl && $explain .= '<br />GUEST [';
683
+ if ( is_user_logged_in() ) {
684
+ if ( 'member' != $cond['guest'][0] ) {
685
+ $expl && $explain .= 'user is logged in';
686
+ $condition_true = false;
687
+ }
688
+ } else {
689
+ if ( 'guest' != $cond['guest'][0] ) {
690
+ $expl && $explain .= 'user not logged in';
691
+ $condition_true = false;
692
+ }
693
+ }
694
+ $expl && $explain .= '] ';
695
+ }
696
+
697
+ // Filter for USER ROLES.
698
+ if ( $condition_true && ! empty( $cond['roles'] ) && is_array( $cond['roles'] ) ) {
699
+ $expl && $explain .= '<br />ROLE [';
700
+ if ( ! is_user_logged_in() ) {
701
+ $expl && $explain .= 'user not logged in';
702
+ $condition_true = false;
703
+ } else {
704
+ global $current_user;
705
+ $has_role = false;
706
+ foreach ( $current_user->roles as $user_role ) {
707
+ if ( in_array( $user_role, $cond['roles'] ) ) {
708
+ $expl && $explain .= 'ok:' . $user_role;
709
+ $has_role = true;
710
+ break;
711
+ }
712
+ }
713
+ if ( ! $has_role ) {
714
+ $expl && $explain .= 'invalid role';
715
+ $condition_true = false;
716
+ }
717
+ }
718
+ $expl && $explain .= '] ';
719
+ }
720
+
721
+ // Filter for MEMBERSHIP Level.
722
+ if ( $condition_true && ! empty( $cond['membership'] ) ) {
723
+ $expl && $explain .= '<br />MEMBERSHIP [';
724
+ if ( class_exists( 'Membership_Factory' ) ) {
725
+ $has_level = false;
726
+ $wpuser = get_userdata( get_current_user_id() );
727
+
728
+ $is_admin = $wpuser && (
729
+ $wpuser->has_cap( 'membershipadmin' ) ||
730
+ $wpuser->has_cap( 'manage_options' ) ||
731
+ is_super_admin()
732
+ );
733
+
734
+ if ( $is_admin ) {
735
+ $expl && $explain .= 'is admin';
736
+ $has_level = true;
737
+ } else {
738
+ $factory = new Membership_Factory();
739
+ $user = $factory->get_member( get_current_user_id() );
740
+ $levels = $user->get_level_ids();
741
+
742
+ if ( ! is_array( $levels ) ) { $levels = array( $levels ); }
743
+
744
+ foreach ( $cond['membership'] as $need_level_id ) {
745
+ if ( empty( $need_level_id ) ) { continue; }
746
+ foreach ( $levels as $the_level ) {
747
+ if ( $the_level->level_id == $need_level_id ) {
748
+ $expl && $explain .= 'ok';
749
+ $has_level = true;
750
+ break;
751
+ }
752
+ }
753
+ if ( $has_level ) { break; }
754
+ }
755
+ }
756
+ if ( ! $has_level ) {
757
+ $expl && $explain .= 'invalid user level';
758
+ $condition_true = false;
759
+ }
760
+ }
761
+ $expl && $explain .= '] ';
762
+ }
763
+
764
+ // Filter for MEMBERSHIP2 Level.
765
+ if ( $condition_true && ! empty( $cond['membership2'] ) ) {
766
+ $expl && $explain .= '<br />MEMBERSHIP2 [';
767
+ if ( apply_filters( 'ms_active', false ) ) {
768
+ $is_member = false;
769
+ $member = MS_Plugin::$api->get_current_member();
770
+
771
+ if ( $member->is_admin_user() ) {
772
+ $expl && $explain .= 'is admin';
773
+ $is_member = true;
774
+ } else {
775
+ foreach ( $cond['membership2'] as $membership_id ) {
776
+ if ( $member->has_membership( $membership_id ) ) {
777
+ $is_member = true;
778
+ break;
779
+ }
780
+ }
781
+ }
782
+ if ( ! $is_member ) {
783
+ $expl && $explain .= 'is no member';
784
+ $condition_true = false;
785
+ }
786
+ }
787
+ $expl && $explain .= '] ';
788
+ }
789
+
790
+ // Filter for PRO-SITE Level.
791
+ if ( $condition_true && ! empty( $cond['prosite'] ) ) {
792
+ $expl && $explain .= '<br />PROSITE [';
793
+ // not implemented yet...
794
+ $expl && $explain .= '] ';
795
+ }
796
+
797
+ // Filter for SPECIAL PAGES.
798
+ if ( $condition_true && ! empty( $cond['pagetypes'] ) && is_array( $cond['pagetypes'] ) ) {
799
+ $expl && $explain .= '<br />PAGETYPE [';
800
+ $is_type = false;
801
+ foreach ( $cond['pagetypes'] as $type ) {
802
+ if ( $is_type ) {
803
+ break;
804
+ }
805
+
806
+ switch ( $type ) {
807
+ case 'e404':
808
+ $is_type = $is_type || is_404();
809
+ break;
810
+ case 'single':
811
+ $is_type = $is_type || is_singular();
812
+ break;
813
+ case 'search':
814
+ $is_type = $is_type || is_search();
815
+ break;
816
+ case 'archive':
817
+ $is_type = $is_type || is_archive();
818
+ break;
819
+ case 'preview':
820
+ $is_type = $is_type || is_preview();
821
+ break;
822
+ case 'day':
823
+ $is_type = $is_type || is_day();
824
+ break;
825
+ case 'month':
826
+ $is_type = $is_type || is_month();
827
+ break;
828
+ case 'year':
829
+ $is_type = $is_type || is_year();
830
+ break;
831
+ case 'frontpage':
832
+ if ( current_theme_supports( 'infinite-scroll' ) ) {
833
+ $is_type = $is_type || is_front_page();
834
+ } else {
835
+ $is_type = $is_type || ( is_front_page() && ! is_paged() );
836
+ }
837
+ break;
838
+ case 'posts':
839
+ case 'home':
840
+ $is_type = $is_type || is_home();
841
+ break;
842
+ }
843
+ $expl && $explain .= $type . ':' . ($is_type ? 'ok' : 'invalid');
844
+ }
845
+ if ( ! $is_type ) {
846
+ $condition_true = false;
847
+ }
848
+ $expl && $explain .= '] ';
849
+ }
850
+
851
+ // Filter for POST-TYPE.
852
+ if ( $condition_true && ! empty( $cond['posttypes'] ) ) {
853
+ $posttype = get_post_type();
854
+ $expl && $explain .= '<br />POSTTYPE-' . strtoupper( $posttype ) . ' [';
855
+
856
+ if ( ! in_array( $posttype, $cond['posttypes'] ) ) {
857
+ $expl && $explain .= 'invalid posttype';
858
+ $condition_true = false;
859
+ } else {
860
+ // Filter for SPECIFIC POSTS.
861
+ if ( ! empty( $cond[ 'pt-' . $posttype ] ) ) {
862
+ if ( ! in_array( get_the_ID(), $cond[ 'pt-' . $posttype ] ) ) {
863
+ $expl && $explain .= 'invalid post_id';
864
+ $condition_true = false;
865
+ }
866
+ }
867
+ }
868
+ if ( $condition_true ) {
869
+ $expl && $explain .= 'ok';
870
+ }
871
+ $expl && $explain .= '] ';
872
+ }
873
+
874
+ if ( $condition_true ) {
875
+ // TAXONOMY condition.
876
+ $tax_query = null;
877
+ if ( isset( $wp_query->tax_query ) ) {
878
+ $tax_query = $wp_query->tax_query->queries;
879
+ }
880
+ $tax_type = $tax_terms = false;
881
+ if ( ! empty( $tax_query ) && is_array( $tax_query ) ) {
882
+ $tax_type = $tax_query[0]['taxonomy'];
883
+ $tax_terms = $tax_query[0]['terms'];
884
+ }
885
+
886
+ foreach ( $Tax_list as $tax_item ) {
887
+ if ( ! $condition_true ) {
888
+ break;
889
+ }
890
+
891
+ $tax_key = 'tax-' . $tax_item->name;
892
+ if ( isset( $cond[ $tax_key ] ) && ! empty( $cond[ $tax_key ] ) ) {
893
+ $expl && $explain .= '<br />TAX-' . strtoupper( $tax_item->name ) . ' [';
894
+ $has_term = false;
895
+
896
+ if ( $tax_type && $tax_type == $tax_item->name ) {
897
+ // Check if we did filter for the specific taxonomy.
898
+ foreach ( $tax_terms as $slug ) {
899
+ $term_data = get_term_by( 'slug', $slug, $tax_type );
900
+ if ( in_array( $term_data->term_id, $cond[ $tax_key ] ) ) {
901
+ $expl && $explain .= 'ok:' . $term_data->term_id;
902
+ $has_term = true;
903
+ }
904
+ }
905
+ } else {
906
+ // Check if current post has the specific taxonomy.
907
+ foreach ( $cond[ $tax_key ] as $term ) {
908
+ if ( has_term( $term, $tax_item->name ) ) {
909
+ $expl && $explain .= 'ok:' . $term;
910
+ $has_term = true;
911
+ break;
912
+ }
913
+ }
914
+ }
915
+ if ( ! $has_term ) {
916
+ $expl && $explain .= 'no match';
917
+ $condition_true = false;
918
+ }
919
+ $expl && $explain .= '] ';
920
+ }
921
+ }
922
+ }
923
+
924
+ if ( ( 'show' == $action && ! $condition_true ) || ( 'hide' == $action && $condition_true ) ) {
925
+ $show_widget = false;
926
+ }
927
+
928
+ $expl && do_action(
929
+ 'cs_explain',
930
+ ($condition_true ? '<span style="color:#090">Do</span>' : '<span style="color:#900">Dont</span>') .
931
+ ' <b>' . $action . '</b> - ' .
932
+ $explain
933
+ );
934
+
935
+ return $show_widget;
936
+ }
937
+
938
+ //
939
+ // ========== AJAX Handler
940
+ //
941
+
942
+ /**
943
+ * Ajax handler. If the action is processed the request is closed via die()
944
+ *
945
+ * @since 2.0.9.7
946
+ * @param string $action
947
+ */
948
+ public function handle_ajax( $action ) {
949
+ // The ajax request was not meant for us...
950
+ if ( 'visibility' != $action ) {
951
+ return false;
952
+ }
953
+
954
+ $data = array();
955
+ if ( isset( $_GET['tag'] ) ) {
956
+ $data = $this->ajax_data_terms( @$_GET['tag'], @$_REQUEST['q'] );
957
+ } elseif ( isset( $_GET['posttype'] ) ) {
958
+ $data = $this->ajax_data_posts( @$_GET['posttype'], @$_REQUEST['q'] );
959
+ }
960
+
961
+ self::json_response( array( 'items' => $data ) );
962
+ }
963
+
964
+ /**
965
+ * Returns an array with tags that contain the specified search term.
966
+ *
967
+ * @since 2.0.9.7
968
+ * @param string $term_name Taxonomy type.
969
+ * @param string $search Search term.
970
+ * @return array
971
+ */
972
+ protected function ajax_data_terms( $term_name, $search ) {
973
+ $data = array();
974
+ $tags = get_terms(
975
+ $term_name,
976
+ array(
977
+ 'hide_empty' => false,
978
+ 'search' => $search,
979
+ )
980
+ );
981
+
982
+ foreach ( $tags as $tag ) {
983
+ $key = $tag->term_id;
984
+ $name = $tag->name;
985
+ $data[] = array(
986
+ 'key' => $key,
987
+ 'val' => esc_html( $name ),
988
+ );
989
+ }
990
+
991
+ return $data;
992
+ }
993
+
994
+ /**
995
+ * Returns an array with post-titles that contain the specified search term.
996
+ *
997
+ * @since 2.0.9.7
998
+ * @param string $posttype Post-type to search.
999
+ * @param string $search Search term.
1000
+ * @return array
1001
+ */
1002
+ protected function ajax_data_posts( $posttype, $search ) {
1003
+ $data = array();
1004
+ $posts = get_posts(
1005
+ array(
1006
+ 'post_type' => $posttype,
1007
+ 'order_by' => 'title',
1008
+ 'order' => 'ASC',
1009
+ 'numberposts' => '0',
1010
+ 's' => $search,
1011
+ )
1012
+ );
1013
+
1014
+ foreach ( $posts as $post ) {
1015
+ $key = $post->ID;
1016
+ $name = $post->post_title;
1017
+ $data[] = array(
1018
+ 'key' => $key,
1019
+ 'val' => esc_html( $name ),
1020
+ );
1021
+ }
1022
+
1023
+ return $data;
1024
+ }
1025
+ };
inc/class-custom-sidebars-widgets.php CHANGED
@@ -39,6 +39,16 @@ class CustomSidebarsWidgets extends CustomSidebars {
39
  array( $this, 'init_admin_head' )
40
  );
41
  }
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
  /**
@@ -69,5 +79,4 @@ class CustomSidebarsWidgets extends CustomSidebars {
69
  $classes .= ' no-auto-init ';
70
  return $classes;
71
  }
72
-
73
- };
39
  array( $this, 'init_admin_head' )
40
  );
41
  }
42
+ add_action( 'widgets_admin_page', array( $this, 'add_div_start' ) );
43
+ add_action( 'sidebar_admin_page', array( $this, 'add_div_end' ) );
44
+ }
45
+
46
+ public function add_div_start() {
47
+ echo '<div class="cs-wrap">';
48
+ }
49
+
50
+ public function add_div_end() {
51
+ echo '</div>';
52
  }
53
 
54
  /**
79
  $classes .= ' no-auto-init ';
80
  return $classes;
81
  }
82
+ };
 
inc/class-custom-sidebars.php CHANGED
@@ -4,9 +4,13 @@
4
  require_once CSB_INC_DIR . 'class-custom-sidebars-widgets.php';
5
  require_once CSB_INC_DIR . 'class-custom-sidebars-editor.php';
6
  require_once CSB_INC_DIR . 'class-custom-sidebars-replacer.php';
7
-
 
 
8
  require_once CSB_INC_DIR . 'class-custom-sidebars-explain.php';
9
 
 
 
10
 
11
  /**
12
  * Main plugin file.
@@ -147,11 +151,6 @@ class CustomSidebars {
147
  }
148
  }
149
 
150
- add_action(
151
- 'in_widget_form',
152
- array( $this, 'in_widget_form' ),
153
- 10, 1
154
- );
155
  }
156
 
157
  /**
@@ -741,49 +740,10 @@ class CustomSidebars {
741
  return 1 + self::get_category_level( $cat->category_parent );
742
  }
743
 
744
-
745
- // =========================================================================
746
- // == ACTION HOOKS
747
- // =========================================================================
748
-
749
-
750
- /**
751
- * Callback for in_widget_form action
752
- *
753
- * Free version only.
754
- *
755
- * @since 2.0.1
756
- */
757
- public function in_widget_form( $widget ) {
758
-
759
- if ( CSB_IS_PRO ) { return; }
760
- ?>
761
- <input type="hidden" name="csb-buttons" value="0" />
762
- <?php if ( ! isset( $_POST['csb-buttons'] ) ) : ?>
763
- <div class="csb-pro-layer csb-pro-<?php echo esc_attr( $widget->id ); ?>">
764
- <a href="#" class="button csb-clone-button"><?php _e( 'Clone', 'custom-sidebars' ); ?></a>
765
- <a href="#" class="button csb-visibility-button"><span class="dashicons dashicons-visibility"></span> <?php _e( 'Visibility', 'custom-sidebars' ); ?></a>
766
- <a href="<?php echo esc_url( CustomSidebars::$pro_url ); ?>" target="_blank" class="pro-info">
767
- <?php printf(
768
- __( 'Pro Version Features', 'custom-sidebars' ),
769
- CustomSidebars::$pro_url
770
- ); ?>
771
- </a>
772
- </div>
773
- <?php
774
- endif;
775
-
776
- }
777
-
778
-
779
  // =========================================================================
780
  // == AJAX FUNCTIONS
781
  // =========================================================================
782
 
783
-
784
-
785
-
786
-
787
  /**
788
  * Output JSON data and die()
789
  *
4
  require_once CSB_INC_DIR . 'class-custom-sidebars-widgets.php';
5
  require_once CSB_INC_DIR . 'class-custom-sidebars-editor.php';
6
  require_once CSB_INC_DIR . 'class-custom-sidebars-replacer.php';
7
+ require_once CSB_INC_DIR . 'class-custom-sidebars-cloning.php';
8
+ require_once CSB_INC_DIR . 'class-custom-sidebars-visibility.php';
9
+ require_once CSB_INC_DIR . 'class-custom-sidebars-export.php';
10
  require_once CSB_INC_DIR . 'class-custom-sidebars-explain.php';
11
 
12
+ require_once CSB_INC_DIR . 'class-custom-sidebars-advertisement.php';
13
+
14
 
15
  /**
16
  * Main plugin file.
151
  }
152
  }
153
 
 
 
 
 
 
154
  }
155
 
156
  /**
740
  return 1 + self::get_category_level( $cat->category_parent );
741
  }
742
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  // =========================================================================
744
  // == AJAX FUNCTIONS
745
  // =========================================================================
746
 
 
 
 
 
747
  /**
748
  * Output JSON data and die()
749
  *
js/cs-cloning.js ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! Custom Sidebars - v2.1.08
2
+ * https://premium.wpmudev.org/project/custom-sidebars-pro/
3
+ * Copyright (c) 2016; * Licensed GPLv2+ */
4
+ /*global jQuery:false */
5
+ /*global window:false */
6
+ /*global document:false */
7
+ /*global wp:false */
8
+ /*global wpmUi:false */
9
+
10
+ jQuery(function init_cloning() {
11
+ var $doc = jQuery( document ),
12
+ $all = jQuery( '#widgets-right' ),
13
+ is_cloning = false;
14
+
15
+ /**
16
+ * Moves the "Clone" button next to the save button.
17
+ */
18
+ var init_widget = function init_widget( ev, el ) {
19
+ var $widget = jQuery( el ).closest( '.widget' ),
20
+ $btn = $widget.find( '.csb-clone-button' ),
21
+ $target = $widget.find( '.widget-control-actions .widget-control-save' ),
22
+ $spinner = $widget.find( '.widget-control-actions .spinner' ),
23
+ $btn_save = $widget.find( '.widget-control-save' );
24
+
25
+ if ( $widget.data( '_csb_cloning' ) ) {
26
+ return;
27
+ }
28
+
29
+ $spinner.insertBefore( $target ).css({ 'float': 'left' });
30
+ $btn.insertBefore( $target ).click( clone_widget );
31
+ $btn_save.click( prepare_update_group );
32
+
33
+ $widget.data( '_csb_cloning', true );
34
+ };
35
+
36
+ /**
37
+ * Updates the group-counter when a widget is added.
38
+ */
39
+ var update_group_counter = function update_group_counter( ev, el ) {
40
+ // We do NOT want to change the group-id when we clone a widget...
41
+ if ( is_cloning ) { return false; }
42
+
43
+ var $widget = jQuery( el ).closest( '.widget' ),
44
+ $widget_group = $widget.find( 'input.csb-clone-group' ),
45
+ group_id = parseInt( $widget_group.val() ),
46
+ check = null;
47
+
48
+ do {
49
+ check = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' );
50
+ if ( ! check.length || ( 1 === check.length && check[0] === $widget_group[0] ) ) {
51
+ break;
52
+ } else {
53
+ group_id += 1;
54
+ }
55
+ }
56
+ while ( true );
57
+
58
+ $widget_group.val( group_id );
59
+ update_template_groups();
60
+ };
61
+
62
+ /**
63
+ * Updates all group_id values for the widget-templates to the next free id.
64
+ */
65
+ var update_template_groups = function update_template_groups() {
66
+ var $groups = jQuery( '#widgets-left input.csb-clone-group' ),
67
+ next_id = parseInt( $groups.first().val() );
68
+
69
+ while ( $all.find( 'input.csb-clone-group[value="' + next_id + '"]' ).length ) {
70
+ next_id += 1;
71
+ }
72
+
73
+ $groups.val( next_id );
74
+ };
75
+
76
+ /**
77
+ * Viually highlights all widgets of the same group.
78
+ */
79
+ var mark_group = function mark_group( ev ) {
80
+ var $widget = jQuery( this ).closest( '.widget' ),
81
+ group_id = $widget.find( 'input.csb-clone-group' ).val(),
82
+ $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' );
83
+
84
+ if ( isNaN( group_id ) || group_id < 1 ) {
85
+ return;
86
+ }
87
+
88
+ $members.addClass('csb-marker');
89
+ $widget.removeClass('csb-marker');
90
+ };
91
+
92
+ /**
93
+ * Removes the visual highlighting of group widgets.
94
+ */
95
+ var unmark_group = function unmark_group( ev ) {
96
+ var $marked = jQuery( '.widget.csb-marker' );
97
+ $marked.removeClass('csb-marker');
98
+ };
99
+
100
+ /**
101
+ * Adds icons to all widgets that are inside a group.
102
+ */
103
+ var init_group_icons = function init_group_icons() {
104
+ var $groups = $all.find( 'input.csb-clone-group' );
105
+
106
+ $groups.each(function() {
107
+ var group_id = jQuery( this ).val(),
108
+ $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ),
109
+ $titles = $members.find( '.widget-title h4, .widget-title h3' ),
110
+ action = 'add';
111
+
112
+ if ( isNaN( group_id ) || group_id < 1 ) {
113
+ action = 'remove';
114
+ }
115
+ if ( $members.length < 2 ) {
116
+ action = 'remove';
117
+ }
118
+
119
+ // Always remove the icons from the group.
120
+ $titles.removeClass( 'csb-group group-active' )
121
+ .find( '.btn-clone-group' ).remove();
122
+ $members.removeAttr( 'data-csb-icon' );
123
+
124
+ // If action is "add" then we add the icons again.
125
+ if ( action === 'add' ) {
126
+ $titles.addClass( 'csb-group group-active' )
127
+ .prepend( '<i class="dashicons dashicons-admin-links btn-clone-group"></i> ' );
128
+ $titles.find( '.btn-clone-group' )
129
+ .hover( mark_group, unmark_group )
130
+ .click( toggle_group );
131
+ }
132
+ });
133
+ };
134
+
135
+ /**
136
+ * Remove widget from group/assign to group again (only works until widget
137
+ * was saved.)
138
+ */
139
+ var toggle_group = function toggle_group( ev ) {
140
+ var $widget = jQuery( this ).closest( '.widget' ),
141
+ $title = $widget.find( '.widget-title h4' ),
142
+ $icon = $title.find( '.btn-clone-group' ),
143
+ $group = $widget.find( 'input.csb-clone-group' );
144
+
145
+ ev.preventDefault();
146
+ ev.stopPropagation();
147
+ if ( $title.hasClass( 'group-active' ) ) {
148
+ $title.removeClass( 'group-active' );
149
+ $icon.removeClass('dashicons-admin-links').addClass('dashicons-editor-unlink');
150
+ $group.data( 'group', $group.val() );
151
+ $group.val( 0 );
152
+ unmark_group();
153
+ } else {
154
+ $title.addClass( 'group-active' );
155
+ $icon.addClass('dashicons-admin-links').removeClass('dashicons-editor-unlink');
156
+ $group.val( $group.data( 'group' ) );
157
+ mark_group.call( this, [ev] );
158
+ }
159
+ return false;
160
+ };
161
+
162
+ /**
163
+ * Clones the widget:
164
+ * Add a new widget using default WordPress JS API and then update all the
165
+ * input values of the new widget to match the original widget.
166
+ */
167
+ var clone_widget = function clone_widget( ev ) {
168
+ var $widget = jQuery( this ).closest( '.widget' ),
169
+ $available = jQuery( '#widgets-left' ),
170
+ $chooser = jQuery( '.widgets-chooser' ),
171
+ $content = jQuery( '#wpbody-content' );
172
+
173
+ ev.preventDefault();
174
+ is_cloning = true;
175
+
176
+ // 1. If the current widget is new then first save the current widget
177
+ var state = $widget.find( 'input.csb-clone-state' ).val();
178
+ if ( 'new' === state ) {
179
+ window.wpWidgets.save( $widget, 0, 0, 0 );
180
+ }
181
+
182
+ // 2. Close any open chooser
183
+ window.wpWidgets.clearWidgetSelection();
184
+ $chooser.slideUp( 200, function() {
185
+ $chooser.hide();
186
+ $content.append( this );
187
+ });
188
+
189
+ // 3. Find the "widget-in-question".
190
+ var class_name = $widget.find('input.id_base').val(),
191
+ $base = $available.find('input.id_base[value="' + class_name + '"]'),
192
+ $in_question = $base.closest( '.widget' );
193
+ $in_question.addClass( 'widget-in-question' );
194
+
195
+ // 4. Provide data about the origin widget.
196
+ var group_id = $widget.find( 'input.csb-clone-group' ).val(),
197
+ $contr = $in_question.find( '.widget-control-actions' ),
198
+ $group = $in_question.find( 'input.csb-clone-group' ),
199
+ $state = $in_question.find( 'input.csb-clone-state' );
200
+ $group.val( group_id );
201
+ $state.val( 'empty' );
202
+
203
+ // 5. Select the current sidebar in the chooser.
204
+ var $sidebar = $widget.closest( '.widgets-sortables' ),
205
+ sb_id = $sidebar.attr( 'id' );
206
+ $chooser.find ( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' );
207
+ $chooser.find( 'li' ).each( function() {
208
+ var $li = jQuery( this );
209
+ if ( sb_id === $li.data('sidebarId') ) {
210
+ $li.addClass( 'widgets-chooser-selected' ).focus();
211
+ }
212
+ });
213
+
214
+ // 6. Add the new widget to the sidebar.
215
+ // This will directly trigger the ajax command to save the widget.
216
+ window.wpWidgets.addWidget( $chooser );
217
+
218
+ // 7. Remove the custom elements and information again.
219
+ window.wpWidgets.clearWidgetSelection();
220
+ update_template_groups();
221
+
222
+ is_cloning = false;
223
+
224
+ return false;
225
+ };
226
+
227
+ /**
228
+ * Saves the specified widget if the clone-state is "empty".
229
+ */
230
+ var populate_widget = function populate_widget( $widget ) {
231
+ var $state = $widget.find( 'input.csb-clone-state' );
232
+
233
+ if ( $state.val() === 'empty' ) {
234
+ $widget.addClass( 'wpmui-loading' );
235
+ window.wpWidgets.save( $widget, 0, 1, 0 );
236
+ }
237
+ };
238
+
239
+ /**
240
+ * Update all widgets belonging to the same group.
241
+ */
242
+ var prepare_update_group = function prepare_update_group( ev ) {
243
+ var $widget = jQuery( this ).closest( '.widget' ),
244
+ group_id = $widget.find( 'input.csb-clone-group' ).val(),
245
+ $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ).not( $widget );
246
+
247
+ $members.each(function() {
248
+ var $item = jQuery( this ),
249
+ $state = $item.find( 'input.csb-clone-state' );
250
+
251
+ $item.addClass('wpmui-loading').attr( 'data-reload', true );
252
+ });
253
+ };
254
+
255
+ /**
256
+ * Update all widgets belonging to the same group.
257
+ */
258
+ var update_group_widgets = function update_group_widgets( el ) {
259
+ var $widgets = $all.find( '.widget[data-reload]' );
260
+
261
+ $widgets.each(function() {
262
+ var $item = jQuery( this ),
263
+ $state = $item.find( 'input.csb-clone-state' );
264
+
265
+ $state.val( 'empty' );
266
+ $item.removeAttr( 'data-reload' );
267
+ window.wpWidgets.save( $item, 0, 0, 0 );
268
+ });
269
+ };
270
+
271
+ /**
272
+ * Global ajax observer reacts to all ajax responses. We need this to find
273
+ * out when a new widget is saved for the first time.
274
+ */
275
+ var ajax_observer = function ajax_observer( ev, xhr, opt, resp ) {
276
+ var data = ( 'string' === typeof opt.data ? opt.data : '' ),
277
+ find_action = data.match( /^.*&action=([^&]+).*$/ ),
278
+ find_widget = data.match( /^.*&widget-id=([^&]+).*$/ ),
279
+ action = (find_action && find_action.length === 2 ? find_action[1] : ''),
280
+ widget = (find_widget && find_widget.length === 2 ? find_widget[1] : '');
281
+
282
+ if ( ! widget.length ) {
283
+ return;
284
+ }
285
+
286
+ var $base = jQuery( '.widget input.widget-id[value="' + widget + '"]' ),
287
+ $widget = $base.closest( '.widget' );
288
+
289
+ switch ( action ) {
290
+ case 'save-widget':
291
+ $widget.removeClass( 'wpmui-loading' );
292
+ if ( ! resp.length ) {
293
+ // Populate widget with data from group, if required.
294
+ populate_widget( $widget );
295
+ } else if ( resp.match( /^deleted:/ ) ) {
296
+ // Widget was deleted and is removed with animation.
297
+ window.setTimeout( init_group_icons, 400 );
298
+ } else {
299
+ // Existing widget was updated.
300
+ init_group_icons();
301
+ update_group_widgets( $widget );
302
+ }
303
+ break;
304
+
305
+ default:
306
+ // Unrelated ajax event.
307
+ }
308
+ };
309
+
310
+
311
+ $all.find( '.widget' ).each( init_widget );
312
+ $doc.on( 'widget-added', init_widget );
313
+ $doc.on( 'widget-added', update_group_counter );
314
+ $doc.ajaxSuccess( ajax_observer );
315
+
316
+ init_group_icons();
317
+ update_template_groups();
318
+ });
js/cs-cloning.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*! Custom Sidebars - v2.1.08
2
+ * https://premium.wpmudev.org/project/custom-sidebars-pro/
3
+ * Copyright (c) 2016; * Licensed GPLv2+ */
4
+ jQuery(function(){var e=jQuery(document),t=jQuery("#widgets-right"),i=!1,n=function n(e,t){var i=jQuery(t).closest(".widget"),n=i.find(".csb-clone-button"),s=i.find(".widget-control-actions .widget-control-save"),a=i.find(".widget-control-actions .spinner"),d=i.find(".widget-control-save");i.data("_csb_cloning")||(a.insertBefore(s).css({"float":"left"}),n.insertBefore(s).click(l),d.click(g),i.data("_csb_cloning",!0))},s=function s(e,n){if(i)return!1;for(var s=jQuery(n).closest(".widget"),d=s.find("input.csb-clone-group"),o=parseInt(d.val()),c=null;;){if(c=t.find('input.csb-clone-group[value="'+o+'"]'),!c.length||1===c.length&&c[0]===d[0])break;o+=1}d.val(o),a()},a=function a(){for(var e=jQuery("#widgets-left input.csb-clone-group"),i=parseInt(e.first().val());t.find('input.csb-clone-group[value="'+i+'"]').length;)i+=1;e.val(i)},d=function d(){var e=jQuery(this).closest(".widget"),i=e.find("input.csb-clone-group").val(),n=t.find('input.csb-clone-group[value="'+i+'"]').closest(".widget");isNaN(i)||1>i||(n.addClass("csb-marker"),e.removeClass("csb-marker"))},o=function o(){var e=jQuery(".widget.csb-marker");e.removeClass("csb-marker")},c=function c(){var e=t.find("input.csb-clone-group");e.each(function(){var e=jQuery(this).val(),i=t.find('input.csb-clone-group[value="'+e+'"]').closest(".widget"),n=i.find(".widget-title h4, .widget-title h3"),s="add";(isNaN(e)||1>e)&&(s="remove"),2>i.length&&(s="remove"),n.removeClass("csb-group group-active").find(".btn-clone-group").remove(),i.removeAttr("data-csb-icon"),"add"===s&&(n.addClass("csb-group group-active").prepend('<i class="dashicons dashicons-admin-links btn-clone-group"></i> '),n.find(".btn-clone-group").hover(d,o).click(r))})},r=function r(e){var t=jQuery(this).closest(".widget"),i=t.find(".widget-title h4"),n=i.find(".btn-clone-group"),s=t.find("input.csb-clone-group");return e.preventDefault(),e.stopPropagation(),i.hasClass("group-active")?(i.removeClass("group-active"),n.removeClass("dashicons-admin-links").addClass("dashicons-editor-unlink"),s.data("group",s.val()),s.val(0),o()):(i.addClass("group-active"),n.addClass("dashicons-admin-links").removeClass("dashicons-editor-unlink"),s.val(s.data("group")),d.call(this,[e])),!1},l=function l(e){var t=jQuery(this).closest(".widget"),n=jQuery("#widgets-left"),s=jQuery(".widgets-chooser"),d=jQuery("#wpbody-content");e.preventDefault(),i=!0;var o=t.find("input.csb-clone-state").val();"new"===o&&window.wpWidgets.save(t,0,0,0),window.wpWidgets.clearWidgetSelection(),s.slideUp(200,function(){s.hide(),d.append(this)});var c=t.find("input.id_base").val(),r=n.find('input.id_base[value="'+c+'"]'),l=r.closest(".widget");l.addClass("widget-in-question");var u=t.find("input.csb-clone-group").val(),g=(l.find(".widget-control-actions"),l.find("input.csb-clone-group")),p=l.find("input.csb-clone-state");g.val(u),p.val("empty");var v=t.closest(".widgets-sortables"),f=v.attr("id");return s.find(".widgets-chooser-selected").removeClass("widgets-chooser-selected"),s.find("li").each(function(){var e=jQuery(this);f===e.data("sidebarId")&&e.addClass("widgets-chooser-selected").focus()}),window.wpWidgets.addWidget(s),window.wpWidgets.clearWidgetSelection(),a(),i=!1,!1},u=function u(e){var t=e.find("input.csb-clone-state");"empty"===t.val()&&(e.addClass("wpmui-loading"),window.wpWidgets.save(e,0,1,0))},g=function g(){var e=jQuery(this).closest(".widget"),i=e.find("input.csb-clone-group").val(),n=t.find('input.csb-clone-group[value="'+i+'"]').closest(".widget").not(e);n.each(function(){var e=jQuery(this);e.find("input.csb-clone-state"),e.addClass("wpmui-loading").attr("data-reload",!0)})},p=function p(){var e=t.find(".widget[data-reload]");e.each(function(){var e=jQuery(this),t=e.find("input.csb-clone-state");t.val("empty"),e.removeAttr("data-reload"),window.wpWidgets.save(e,0,0,0)})},v=function v(e,t,i,n){var s="string"==typeof i.data?i.data:"",a=s.match(/^.*&action=([^&]+).*$/),d=s.match(/^.*&widget-id=([^&]+).*$/),o=a&&2===a.length?a[1]:"",r=d&&2===d.length?d[1]:"";if(r.length){var l=jQuery('.widget input.widget-id[value="'+r+'"]'),g=l.closest(".widget");switch(o){case"save-widget":g.removeClass("wpmui-loading"),n.length?n.match(/^deleted:/)?window.setTimeout(c,400):(c(),p(g)):u(g);break;default:}}};t.find(".widget").each(n),e.on("widget-added",n),e.on("widget-added",s),e.ajaxSuccess(v),c(),a()});
js/cs-visibility.js ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! Custom Sidebars - v2.1.08
2
+ * https://premium.wpmudev.org/project/custom-sidebars-pro/
3
+ * Copyright (c) 2016; * Licensed GPLv2+ */
4
+ /*global jQuery:false */
5
+ /*global window:false */
6
+ /*global document:false */
7
+ /*global wp:false */
8
+ /*global wpmUi:false */
9
+
10
+ jQuery(function init_visibility() {
11
+ var $doc = jQuery( document );
12
+
13
+ /**
14
+ * Moves the "Visibility" button next to the save button.
15
+ */
16
+ var init_widget = function init_widget( ev, el ) {
17
+ var $widget = jQuery( el ).closest( '.widget' ),
18
+ $btn = $widget.find( '.csb-visibility-button' ),
19
+ $target = $widget.find( '.widget-control-actions .widget-control-save' ),
20
+ $spinner = $widget.find( '.widget-control-actions .spinner' );
21
+
22
+ if ( $widget.data( '_csb_visibility' ) ) {
23
+ return;
24
+ }
25
+
26
+ $spinner.insertBefore( $target ).css({ 'float': 'left' });
27
+ $btn.insertBefore( $target ).click( toggle_section );
28
+ $widget.on( 'click', '.toggle-action b', toggle_action );
29
+ $widget.on( 'csb:update', update_display );
30
+ $widget.on( 'click', '.clear-filter', remove_filter );
31
+ $widget.on( 'click', '.choose-filters', show_filter_menu );
32
+ $widget.on( 'click', '.add-filter', add_filter );
33
+ $widget.on( 'change', 'input[data-lbl-all][data-lbl-single]', toggle_label );
34
+ $widget.on( 'change', 'select.posttype', update_posttypes );
35
+
36
+ $widget.data( '_csb_visibility', true );
37
+ };
38
+
39
+ /**
40
+ * Removes the current filter row from the conditions
41
+ */
42
+ var remove_filter = function remove_filter( ev ) {
43
+ var $me = jQuery( this ),
44
+ $row = $me.closest( '.csb-option-row' ),
45
+ $widget = $me.closest( '.widget' ),
46
+ sel = '.' + jQuery.trim( $row.attr( 'class' ).replace( 'csb-option-row', '') ),
47
+ $add_item = $widget.find( '[data-for="' + sel + '"]' ),
48
+ $input = $row.find( 'input, select, textarea' );
49
+
50
+ ev.preventDefault();
51
+ $add_item.show();
52
+ $row.fadeOut( 400, function clear_values() {
53
+ // After row is hidden clear the input values.
54
+ $input.val('').trigger('change.select2');
55
+ $widget.trigger('csb:update');
56
+ } );
57
+ return false;
58
+ };
59
+
60
+ /**
61
+ * User clicks on a new filter option in the "Add filter" dropdown.
62
+ * Show the filter row.
63
+ */
64
+ var add_filter = function add_filter( ev ) {
65
+ var $me = jQuery( this ),
66
+ sel = $me.data( 'for' ),
67
+ $widget = $me.closest( '.widget' ),
68
+ $always = $widget.find( '.csb-always' ),
69
+ $filter = $widget.find( sel );
70
+
71
+ ev.preventDefault();
72
+ $filter.show();
73
+ $me.hide();
74
+ $always.hide();
75
+ hide_filter_menu();
76
+ $widget.trigger('csb:update');
77
+ return false;
78
+ };
79
+
80
+ /**
81
+ * When a filter block is added or removed we need to show/hide some hints.
82
+ */
83
+ var update_display = function update_display() {
84
+ var $widget = jQuery( this ).closest( '.widget' ),
85
+ $always = $widget.find( '.csb-always' ),
86
+ $rows = $widget.find( '.csb-option-row:visible:not(.csb-action,.csb-always)' );
87
+
88
+ if ( $rows.length === 0 ) {
89
+ $always.show();
90
+ } else {
91
+ $always.hide();
92
+ $rows.find( '.csb-and' ).show();
93
+ $rows.first().find( '.csb-and' ).hide();
94
+ }
95
+ wpmUi.upgrade_multiselect( $widget );
96
+ };
97
+
98
+ /**
99
+ * Let user add a new filter.
100
+ */
101
+ var show_filter_menu = function show_filter_menu( ev ) {
102
+ var $me = jQuery( this ),
103
+ $row = $me.closest( '.csb-option-row' ),
104
+ $menu = $row.find( '.dropdown' );
105
+
106
+ ev.preventDefault();
107
+ $menu.show();
108
+ $doc.one( 'click', hide_filter_menu );
109
+ return false;
110
+ };
111
+
112
+ /**
113
+ * Close the filter menu again.
114
+ */
115
+ var hide_filter_menu = function hide_filter_menu( ev ) {
116
+ jQuery( '.csb-action .dropdown:visible' ).hide();
117
+ };
118
+
119
+ /**
120
+ * Shows or hides the visibility-options for the current widget.
121
+ */
122
+ var toggle_section = function toggle_section( ev ) {
123
+ var $me = jQuery( this ),
124
+ $widget = $me.closest( '.widget' ),
125
+ $section = $widget.find( '.csb-visibility-inner' ),
126
+ $flag = $section.find( '.csb-visible-flag' );
127
+
128
+ ev.preventDefault();
129
+ if ( $flag.val() === '0' ) {
130
+ $flag.val('1');
131
+ $section.show();
132
+ $widget.trigger('csb:update');
133
+ } else {
134
+ $flag.val('0');
135
+ $section.hide();
136
+ }
137
+
138
+ return false;
139
+ };
140
+
141
+ /**
142
+ * Toggles the widget state between "show if" / "hide if"
143
+ */
144
+ var toggle_action = function toggle_action( ev ) {
145
+ var $me = jQuery( this ).closest( 'label' ),
146
+ $widget = $me.closest( '.widget' ),
147
+ sel = '#' + $me.attr( 'for' ),
148
+ $action = $widget.find( sel ),
149
+ state = $action.val(),
150
+ $lbl_show = $widget.find( '.lbl-show-if' ),
151
+ $lbl_hide = $widget.find( '.lbl-hide-if' );
152
+
153
+ ev.preventDefault();
154
+ if ( 'show' !== state ) {
155
+ $lbl_show.show();
156
+ $lbl_hide.hide();
157
+ $action.val( 'show' );
158
+ } else {
159
+ $lbl_show.hide();
160
+ $lbl_hide.show();
161
+ $action.val( 'hide' );
162
+ }
163
+ return false;
164
+ };
165
+
166
+ /**
167
+ * Used for the posttype filter: When user changes the "All posts" checkbox
168
+ * the label will toggle between "All posts" and "Only these posts".
169
+ */
170
+ var toggle_label = function toggle_label( ev ) {
171
+ var $me = jQuery( this ).closest( 'label' ),
172
+ $row = $me.closest( '.csb-detail-row' ),
173
+ $inp = $me.find( 'input[type=checkbox]' ),
174
+ $lbl = $me.find( '.lbl' ),
175
+ $detail = $row.find( '.detail' ),
176
+ $detail_inp = $detail.find( 'input,select,textarea' );
177
+
178
+ if ( $inp.prop( 'checked' ) ) {
179
+ $lbl.text( $inp.data( 'lbl-single' ) );
180
+ $detail.show();
181
+ } else {
182
+ $lbl.text( $inp.data( 'lbl-all' ) );
183
+ $detail.hide();
184
+ $detail_inp.val('').trigger('change.select2');
185
+ }
186
+ };
187
+
188
+ /**
189
+ * When the user changes the posttype-filter show or hide the detail-rows
190
+ * for each posttype.
191
+ */
192
+ var update_posttypes = function update_posttypes( ev ) {
193
+ var $me = jQuery( this ),
194
+ $row = $me.closest( '.csb-option-row' ),
195
+ $types = $row.find( '.csb-detail-row' ),
196
+ types = $me.val(),
197
+ i;
198
+
199
+ $types.addClass( 'csb-hide' );
200
+ if ( types ) {
201
+ for ( i = 0; i < types.length; i += 1 ) {
202
+ $types.filter( '.csb-pt-' + types[i] ).removeClass( 'csb-hide ');
203
+ }
204
+ }
205
+
206
+ $types.each(function check_detail_row() {
207
+ var $detail = jQuery( this ),
208
+ $check = $detail.find( 'input[type=checkbox]' );
209
+
210
+ if ( $detail.hasClass( 'csb-hide' ) ) {
211
+ $detail.hide();
212
+ $check.prop( 'checked', false );
213
+ toggle_label.call( $check );
214
+ } else {
215
+ $detail.show();
216
+ }
217
+ });
218
+ };
219
+
220
+ jQuery( '#widgets-right .widget' ).each( init_widget );
221
+ $doc.on( 'widget-added', init_widget );
222
+ });
js/cs-visibility.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*! Custom Sidebars - v2.1.08
2
+ * https://premium.wpmudev.org/project/custom-sidebars-pro/
3
+ * Copyright (c) 2016; * Licensed GPLv2+ */
4
+ jQuery(function(){var e=jQuery(document),t=function t(e,t){var o=jQuery(t).closest(".widget"),u=o.find(".csb-visibility-button"),f=o.find(".widget-control-actions .widget-control-save"),g=o.find(".widget-control-actions .spinner");o.data("_csb_visibility")||(g.insertBefore(f).css({"float":"left"}),u.insertBefore(f).click(d),o.on("click",".toggle-action b",c),o.on("csb:update",s),o.on("click",".clear-filter",i),o.on("click",".choose-filters",a),o.on("click",".add-filter",n),o.on("change","input[data-lbl-all][data-lbl-single]",l),o.on("change","select.posttype",r),o.data("_csb_visibility",!0))},i=function i(e){var t=jQuery(this),i=t.closest(".csb-option-row"),n=t.closest(".widget"),s="."+jQuery.trim(i.attr("class").replace("csb-option-row","")),a=n.find('[data-for="'+s+'"]'),o=i.find("input, select, textarea");return e.preventDefault(),a.show(),i.fadeOut(400,function(){o.val("").trigger("change.select2"),n.trigger("csb:update")}),!1},n=function n(e){var t=jQuery(this),i=t.data("for"),n=t.closest(".widget"),s=n.find(".csb-always"),a=n.find(i);return e.preventDefault(),a.show(),t.hide(),s.hide(),o(),n.trigger("csb:update"),!1},s=function s(){var e=jQuery(this).closest(".widget"),t=e.find(".csb-always"),i=e.find(".csb-option-row:visible:not(.csb-action,.csb-always)");0===i.length?t.show():(t.hide(),i.find(".csb-and").show(),i.first().find(".csb-and").hide()),wpmUi.upgrade_multiselect(e)},a=function a(t){var i=jQuery(this),n=i.closest(".csb-option-row"),s=n.find(".dropdown");return t.preventDefault(),s.show(),e.one("click",o),!1},o=function o(){jQuery(".csb-action .dropdown:visible").hide()},d=function d(e){var t=jQuery(this),i=t.closest(".widget"),n=i.find(".csb-visibility-inner"),s=n.find(".csb-visible-flag");return e.preventDefault(),"0"===s.val()?(s.val("1"),n.show(),i.trigger("csb:update")):(s.val("0"),n.hide()),!1},c=function c(e){var t=jQuery(this).closest("label"),i=t.closest(".widget"),n="#"+t.attr("for"),s=i.find(n),a=s.val(),o=i.find(".lbl-show-if"),d=i.find(".lbl-hide-if");return e.preventDefault(),"show"!==a?(o.show(),d.hide(),s.val("show")):(o.hide(),d.show(),s.val("hide")),!1},l=function l(){var e=jQuery(this).closest("label"),t=e.closest(".csb-detail-row"),i=e.find("input[type=checkbox]"),n=e.find(".lbl"),s=t.find(".detail"),a=s.find("input,select,textarea");i.prop("checked")?(n.text(i.data("lbl-single")),s.show()):(n.text(i.data("lbl-all")),s.hide(),a.val("").trigger("change.select2"))},r=function r(){var e,t=jQuery(this),i=t.closest(".csb-option-row"),n=i.find(".csb-detail-row"),s=t.val();if(n.addClass("csb-hide"),s)for(e=0;s.length>e;e+=1)n.filter(".csb-pt-"+s[e]).removeClass("csb-hide ");n.each(function(){var e=jQuery(this),t=e.find("input[type=checkbox]");e.hasClass("csb-hide")?(e.hide(),t.prop("checked",!1),l.call(t)):e.show()})};jQuery("#widgets-right .widget").each(t),e.on("widget-added",t)});
lang/custom-sidebars.pot CHANGED
@@ -1,14 +1,14 @@
1
- # Copyright (C) 2016 WPMU DEV
2
  # This file is distributed under the same license as the Custom Sidebars Pro package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Custom Sidebars Pro 2.1.0.8\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/customsidebars\n"
7
- "POT-Creation-Date: 2016-06-22 19:25:23+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2016-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
  "X-Generator: grunt-wp-i18n 0.5.3\n"
@@ -24,82 +24,102 @@ msgstr ""
24
  "X-Poedit-Bookmarks: \n"
25
  "X-Textdomain-Support: yes\n"
26
 
27
- #: inc/class-custom-sidebars-cloning.php:202 inc/class-custom-sidebars.php:737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  msgid "Clone"
29
  msgstr ""
30
 
31
- #: inc/class-custom-sidebars-editor.php:123
32
  #: inc/class-custom-sidebars-export.php:97
33
  msgid "You do not have permission for this"
34
  msgstr ""
35
 
36
- #: inc/class-custom-sidebars-editor.php:198
37
  msgid "Sidebar-name cannot be empty"
38
  msgstr ""
39
 
40
- #: inc/class-custom-sidebars-editor.php:222
41
- #: inc/class-custom-sidebars-editor.php:307
42
  msgid "The sidebar does not exist"
43
  msgstr ""
44
 
45
- #: inc/class-custom-sidebars-editor.php:253
46
  msgid "Created new sidebar <strong>%1$s</strong>"
47
  msgstr ""
48
 
49
- #: inc/class-custom-sidebars-editor.php:261
50
  msgid "Updated sidebar <strong>%1$s</strong>"
51
  msgstr ""
52
 
53
- #: inc/class-custom-sidebars-editor.php:272
54
- #: inc/class-custom-sidebars-editor.php:327
55
  msgid "The sidebar was not found"
56
  msgstr ""
57
 
58
- #: inc/class-custom-sidebars-editor.php:316
59
  msgid "Deleted sidebar <strong>%1$s</strong>"
60
  msgstr ""
61
 
62
- #: inc/class-custom-sidebars-editor.php:385
63
  msgid "Front Page"
64
  msgstr ""
65
 
66
- #: inc/class-custom-sidebars-editor.php:386
67
  msgid "Search Results"
68
  msgstr ""
69
 
70
- #: inc/class-custom-sidebars-editor.php:387
71
  msgid "Not found (404)"
72
  msgstr ""
73
 
74
- #: inc/class-custom-sidebars-editor.php:388
75
  msgid "Any Author Archive"
76
  msgstr ""
77
 
78
- #: inc/class-custom-sidebars-editor.php:389
79
  msgid "Tag Archives"
80
  msgstr ""
81
 
82
- #: inc/class-custom-sidebars-editor.php:390
83
  msgid "Date Archives"
84
  msgstr ""
85
 
86
- #: inc/class-custom-sidebars-editor.php:433
87
  msgid "Post Index"
88
  msgstr ""
89
 
90
- #: inc/class-custom-sidebars-editor.php:437
91
  msgid "%1$s Archives"
92
  msgstr ""
93
 
94
- #: inc/class-custom-sidebars-editor.php:621
95
  msgid "Updated sidebar <strong>%1$s</strong> settings."
96
  msgstr ""
97
 
98
- #: inc/class-custom-sidebars-editor.php:657 views/widgets.php:17
99
  msgid "Sidebars"
100
  msgstr ""
101
 
102
- #: inc/class-custom-sidebars-editor.php:918 views/import.php:127
103
  #: views/widgets.php:47
104
  msgid "Custom Sidebars"
105
  msgstr ""
@@ -108,137 +128,137 @@ msgstr ""
108
  msgid "Import / Export Sidebars"
109
  msgstr ""
110
 
111
- #: inc/class-custom-sidebars-export.php:293
112
- #: inc/class-custom-sidebars-export.php:335
113
  msgid "No file was uploaded"
114
  msgstr ""
115
 
116
- #: inc/class-custom-sidebars-export.php:300
117
  msgid "Import file is too big"
118
  msgstr ""
119
 
120
- #: inc/class-custom-sidebars-export.php:306
121
  msgid "Something went wrong"
122
  msgstr ""
123
 
124
- #: inc/class-custom-sidebars-export.php:329
125
  msgid "Unexpected import format"
126
  msgstr ""
127
 
128
- #: inc/class-custom-sidebars-export.php:600
129
  msgid "Imported %d custom sidebar(s)!"
130
  msgstr ""
131
 
132
- #: inc/class-custom-sidebars-export.php:609
133
  msgid "Plugin options were imported!"
134
  msgstr ""
135
 
136
- #: inc/class-custom-sidebars-export.php:659
137
  msgid "Imported %d widget(s)!"
138
  msgstr ""
139
 
140
- #: inc/class-custom-sidebars-visibility.php:185
141
- #: inc/class-custom-sidebars.php:738
142
  msgid "Visibility"
143
  msgstr ""
144
 
145
- #: inc/class-custom-sidebars-visibility.php:194
146
  msgid "<b>Show</b> widget if:"
147
  msgstr ""
148
 
149
- #: inc/class-custom-sidebars-visibility.php:195
150
  msgid "<b>Hide</b> widget if:"
151
  msgstr ""
152
 
153
- #: inc/class-custom-sidebars-visibility.php:199
154
  msgid "Filters"
155
  msgstr ""
156
 
157
- #: inc/class-custom-sidebars-visibility.php:203
158
  msgid "Date"
159
  msgstr ""
160
 
161
- #: inc/class-custom-sidebars-visibility.php:208
162
  msgid "Guests"
163
  msgstr ""
164
 
165
- #: inc/class-custom-sidebars-visibility.php:213
166
  msgid "Roles"
167
  msgstr ""
168
 
169
- #: inc/class-custom-sidebars-visibility.php:218
170
  msgid "Membership"
171
  msgstr ""
172
 
173
- #: inc/class-custom-sidebars-visibility.php:224
174
  msgid "Membership2"
175
  msgstr ""
176
 
177
- #: inc/class-custom-sidebars-visibility.php:230 views/import.php:303
178
  msgid "Special pages"
179
  msgstr ""
180
 
181
- #: inc/class-custom-sidebars-visibility.php:235
182
  msgid "For posttype"
183
  msgstr ""
184
 
185
- #: inc/class-custom-sidebars-visibility.php:237
186
  msgid "Taxonomy"
187
  msgstr ""
188
 
189
- #: inc/class-custom-sidebars-visibility.php:254
190
  msgid "Always"
191
  msgstr ""
192
 
193
- #: inc/class-custom-sidebars-visibility.php:279
194
- #: inc/class-custom-sidebars-visibility.php:284
195
- #: inc/class-custom-sidebars-visibility.php:293
196
- #: inc/class-custom-sidebars-visibility.php:312
197
- #: inc/class-custom-sidebars-visibility.php:332
198
- #: inc/class-custom-sidebars-visibility.php:351
199
- #: inc/class-custom-sidebars-visibility.php:370
200
- #: inc/class-custom-sidebars-visibility.php:461
201
  msgid "AND"
202
  msgstr ""
203
 
204
- #: inc/class-custom-sidebars-visibility.php:280
205
  msgid "User is not logged-in (Guest)"
206
  msgstr ""
207
 
208
- #: inc/class-custom-sidebars-visibility.php:285
209
  msgid "User is logged-in (Member)"
210
  msgstr ""
211
 
212
- #: inc/class-custom-sidebars-visibility.php:294
213
  msgid "User has role"
214
  msgstr ""
215
 
216
- #: inc/class-custom-sidebars-visibility.php:313
217
  msgid "User has Membership Level"
218
  msgstr ""
219
 
220
- #: inc/class-custom-sidebars-visibility.php:321
221
- #: inc/class-custom-sidebars-visibility.php:341
222
  msgid "(inactive)"
223
  msgstr ""
224
 
225
- #: inc/class-custom-sidebars-visibility.php:333
226
  msgid "User has Membership"
227
  msgstr ""
228
 
229
- #: inc/class-custom-sidebars-visibility.php:352
230
  msgid "On these special pages"
231
  msgstr ""
232
 
233
- #: inc/class-custom-sidebars-visibility.php:371
234
  msgid "On any page of these types"
235
  msgstr ""
236
 
237
- #: inc/class-custom-sidebars-visibility.php:389
238
  msgid "Only for specific %s"
239
  msgstr ""
240
 
241
- #: inc/class-custom-sidebars-visibility.php:390
242
  msgid "Only these %s:"
243
  msgstr ""
244
 
@@ -249,131 +269,135 @@ msgid ""
249
  "\t\t\t\t\t\tto disable accessibility mode and use the %1$s plugin!"
250
  msgstr ""
251
 
252
- #: inc/class-custom-sidebars.php:741
253
  msgid "Pro Version Features"
254
  msgstr ""
255
 
256
- #: views/col-sidebars.php:19
 
 
 
 
 
 
 
 
257
  msgid "(Not available for Home-Page)"
258
  msgstr ""
259
 
260
- #: views/col-sidebars.php:21
261
  msgid "(Not available for Blog-Page)"
262
  msgstr ""
263
 
264
- #: views/import.php:63 views/widgets-export.php:33
265
  msgid "Import"
266
  msgstr ""
267
 
268
- #: views/import.php:70
269
  msgid "Filename"
270
  msgstr ""
271
 
272
- #: views/import.php:74
273
  msgid "Exported on"
274
  msgstr ""
275
 
276
- #: views/import.php:80
277
  msgid "WordPress settings"
278
  msgstr ""
279
 
280
- #: views/import.php:91
281
  msgid "WordPress version"
282
  msgstr ""
283
 
284
- #: views/import.php:96
285
  msgid "Plugin version"
286
  msgstr ""
287
 
288
- #: views/import.php:101
289
  msgid "Theme"
290
  msgstr ""
291
 
292
- #: views/import.php:129
293
  msgid "Mark the sidebars that you want to import."
294
  msgstr ""
295
 
296
- #: views/import.php:134
297
  msgid "Also import all widgets of the selected sidebars."
298
  msgstr ""
299
 
300
- #: views/import.php:141 views/widgets-editor.php:15
301
  msgid "Name"
302
  msgstr ""
303
 
304
- #: views/import.php:142 views/widgets-editor.php:20
305
  msgid "Description"
306
  msgstr ""
307
 
308
- #: views/import.php:143
309
  msgid "Note"
310
  msgstr ""
311
 
312
- #: views/import.php:144
313
- msgid "Widgets"
314
  msgstr ""
315
 
316
- #: views/import.php:152
317
  msgid "Existing sidebar will be replaced!"
318
  msgstr ""
319
 
320
- #: views/import.php:154
321
- msgid "New sidebar will be created"
322
- msgstr ""
323
-
324
- #: views/import.php:208
325
  msgid "(Theme sidebar)"
326
  msgstr ""
327
 
328
- #: views/import.php:234
329
  msgid "Configuration"
330
  msgstr ""
331
 
332
- #: views/import.php:238
333
  msgid "Replaceable sidebars"
334
  msgstr ""
335
 
336
- #: views/import.php:241
337
  msgid "Replaceable Sidebars"
338
  msgstr ""
339
 
340
- #: views/import.php:251
341
  msgid "By post type"
342
  msgstr ""
343
 
344
- #: views/import.php:264
345
  msgid "Post-type archives"
346
  msgstr ""
347
 
348
- #: views/import.php:277
349
  msgid "By category"
350
  msgstr ""
351
 
352
- #: views/import.php:290
353
  msgid "Category archives"
354
  msgstr ""
355
 
356
- #: views/import.php:306
357
  msgid "Main blog page"
358
  msgstr ""
359
 
360
- #: views/import.php:307
361
  msgid "Date archives"
362
  msgstr ""
363
 
364
- #: views/import.php:308
365
  msgid "Author archives"
366
  msgstr ""
367
 
368
- #: views/import.php:309
369
  msgid "Tag archives"
370
  msgstr ""
371
 
372
- #: views/import.php:310
373
  msgid "Search results page"
374
  msgstr ""
375
 
376
- #: views/import.php:320
377
  msgid "Replace the current plugin configuration with the imported configuration."
378
  msgstr ""
379
 
1
+ # Copyright (C) 2017 WPMU DEV
2
  # This file is distributed under the same license as the Custom Sidebars Pro package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Custom Sidebars Pro PLUGIN_VERSION\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/customsidebars\n"
7
+ "POT-Creation-Date: 2017-03-06 07:12:49+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
  "X-Generator: grunt-wp-i18n 0.5.3\n"
24
  "X-Poedit-Bookmarks: \n"
25
  "X-Textdomain-Support: yes\n"
26
 
27
+ #: inc/class-custom-sidebars-advertisement.php:125
28
+ msgid ""
29
+ "Don’t just replace sidebars. Add new sidebars and footers anywhere with "
30
+ "Upfront."
31
+ msgstr ""
32
+
33
+ #: inc/class-custom-sidebars-advertisement.php:126
34
+ msgid "get Upfront free"
35
+ msgstr ""
36
+
37
+ #: inc/class-custom-sidebars-advertisement.php:131
38
+ msgid ""
39
+ "<b>Warning:</b> Some of your plugins may be slowing down your site. Run a "
40
+ "free security and performance scan with WP Checkup."
41
+ msgstr ""
42
+
43
+ #: inc/class-custom-sidebars-advertisement.php:135
44
+ msgid "Scan"
45
+ msgstr ""
46
+
47
+ #: inc/class-custom-sidebars-cloning.php:202 inc/class-custom-sidebars.php:768
48
  msgid "Clone"
49
  msgstr ""
50
 
51
+ #: inc/class-custom-sidebars-editor.php:119
52
  #: inc/class-custom-sidebars-export.php:97
53
  msgid "You do not have permission for this"
54
  msgstr ""
55
 
56
+ #: inc/class-custom-sidebars-editor.php:194
57
  msgid "Sidebar-name cannot be empty"
58
  msgstr ""
59
 
60
+ #: inc/class-custom-sidebars-editor.php:218
61
+ #: inc/class-custom-sidebars-editor.php:301
62
  msgid "The sidebar does not exist"
63
  msgstr ""
64
 
65
+ #: inc/class-custom-sidebars-editor.php:249
66
  msgid "Created new sidebar <strong>%1$s</strong>"
67
  msgstr ""
68
 
69
+ #: inc/class-custom-sidebars-editor.php:257
70
  msgid "Updated sidebar <strong>%1$s</strong>"
71
  msgstr ""
72
 
73
+ #: inc/class-custom-sidebars-editor.php:268
74
+ #: inc/class-custom-sidebars-editor.php:321
75
  msgid "The sidebar was not found"
76
  msgstr ""
77
 
78
+ #: inc/class-custom-sidebars-editor.php:310
79
  msgid "Deleted sidebar <strong>%1$s</strong>"
80
  msgstr ""
81
 
82
+ #: inc/class-custom-sidebars-editor.php:379
83
  msgid "Front Page"
84
  msgstr ""
85
 
86
+ #: inc/class-custom-sidebars-editor.php:380
87
  msgid "Search Results"
88
  msgstr ""
89
 
90
+ #: inc/class-custom-sidebars-editor.php:381
91
  msgid "Not found (404)"
92
  msgstr ""
93
 
94
+ #: inc/class-custom-sidebars-editor.php:382
95
  msgid "Any Author Archive"
96
  msgstr ""
97
 
98
+ #: inc/class-custom-sidebars-editor.php:383
99
  msgid "Tag Archives"
100
  msgstr ""
101
 
102
+ #: inc/class-custom-sidebars-editor.php:384
103
  msgid "Date Archives"
104
  msgstr ""
105
 
106
+ #: inc/class-custom-sidebars-editor.php:425
107
  msgid "Post Index"
108
  msgstr ""
109
 
110
+ #: inc/class-custom-sidebars-editor.php:429
111
  msgid "%1$s Archives"
112
  msgstr ""
113
 
114
+ #: inc/class-custom-sidebars-editor.php:606
115
  msgid "Updated sidebar <strong>%1$s</strong> settings."
116
  msgstr ""
117
 
118
+ #: inc/class-custom-sidebars-editor.php:642 views/widgets.php:17
119
  msgid "Sidebars"
120
  msgstr ""
121
 
122
+ #: inc/class-custom-sidebars-editor.php:894 views/import.php:123
123
  #: views/widgets.php:47
124
  msgid "Custom Sidebars"
125
  msgstr ""
128
  msgid "Import / Export Sidebars"
129
  msgstr ""
130
 
131
+ #: inc/class-custom-sidebars-export.php:320
132
+ #: inc/class-custom-sidebars-export.php:362
133
  msgid "No file was uploaded"
134
  msgstr ""
135
 
136
+ #: inc/class-custom-sidebars-export.php:327
137
  msgid "Import file is too big"
138
  msgstr ""
139
 
140
+ #: inc/class-custom-sidebars-export.php:333
141
  msgid "Something went wrong"
142
  msgstr ""
143
 
144
+ #: inc/class-custom-sidebars-export.php:356
145
  msgid "Unexpected import format"
146
  msgstr ""
147
 
148
+ #: inc/class-custom-sidebars-export.php:633
149
  msgid "Imported %d custom sidebar(s)!"
150
  msgstr ""
151
 
152
+ #: inc/class-custom-sidebars-export.php:642
153
  msgid "Plugin options were imported!"
154
  msgstr ""
155
 
156
+ #: inc/class-custom-sidebars-export.php:692
157
  msgid "Imported %d widget(s)!"
158
  msgstr ""
159
 
160
+ #: inc/class-custom-sidebars-visibility.php:191
161
+ #: inc/class-custom-sidebars.php:769
162
  msgid "Visibility"
163
  msgstr ""
164
 
165
+ #: inc/class-custom-sidebars-visibility.php:200
166
  msgid "<b>Show</b> widget if:"
167
  msgstr ""
168
 
169
+ #: inc/class-custom-sidebars-visibility.php:201
170
  msgid "<b>Hide</b> widget if:"
171
  msgstr ""
172
 
173
+ #: inc/class-custom-sidebars-visibility.php:205
174
  msgid "Filters"
175
  msgstr ""
176
 
177
+ #: inc/class-custom-sidebars-visibility.php:209
178
  msgid "Date"
179
  msgstr ""
180
 
181
+ #: inc/class-custom-sidebars-visibility.php:214
182
  msgid "Guests"
183
  msgstr ""
184
 
185
+ #: inc/class-custom-sidebars-visibility.php:219
186
  msgid "Roles"
187
  msgstr ""
188
 
189
+ #: inc/class-custom-sidebars-visibility.php:224
190
  msgid "Membership"
191
  msgstr ""
192
 
193
+ #: inc/class-custom-sidebars-visibility.php:230
194
  msgid "Membership2"
195
  msgstr ""
196
 
197
+ #: inc/class-custom-sidebars-visibility.php:236 views/import.php:302
198
  msgid "Special pages"
199
  msgstr ""
200
 
201
+ #: inc/class-custom-sidebars-visibility.php:241
202
  msgid "For posttype"
203
  msgstr ""
204
 
205
+ #: inc/class-custom-sidebars-visibility.php:243
206
  msgid "Taxonomy"
207
  msgstr ""
208
 
209
+ #: inc/class-custom-sidebars-visibility.php:260
210
  msgid "Always"
211
  msgstr ""
212
 
213
+ #: inc/class-custom-sidebars-visibility.php:285
214
+ #: inc/class-custom-sidebars-visibility.php:290
215
+ #: inc/class-custom-sidebars-visibility.php:299
216
+ #: inc/class-custom-sidebars-visibility.php:318
217
+ #: inc/class-custom-sidebars-visibility.php:338
218
+ #: inc/class-custom-sidebars-visibility.php:357
219
+ #: inc/class-custom-sidebars-visibility.php:376
220
+ #: inc/class-custom-sidebars-visibility.php:468
221
  msgid "AND"
222
  msgstr ""
223
 
224
+ #: inc/class-custom-sidebars-visibility.php:286
225
  msgid "User is not logged-in (Guest)"
226
  msgstr ""
227
 
228
+ #: inc/class-custom-sidebars-visibility.php:291
229
  msgid "User is logged-in (Member)"
230
  msgstr ""
231
 
232
+ #: inc/class-custom-sidebars-visibility.php:300
233
  msgid "User has role"
234
  msgstr ""
235
 
236
+ #: inc/class-custom-sidebars-visibility.php:319
237
  msgid "User has Membership Level"
238
  msgstr ""
239
 
240
+ #: inc/class-custom-sidebars-visibility.php:327
241
+ #: inc/class-custom-sidebars-visibility.php:347
242
  msgid "(inactive)"
243
  msgstr ""
244
 
245
+ #: inc/class-custom-sidebars-visibility.php:339
246
  msgid "User has Membership"
247
  msgstr ""
248
 
249
+ #: inc/class-custom-sidebars-visibility.php:358
250
  msgid "On these special pages"
251
  msgstr ""
252
 
253
+ #: inc/class-custom-sidebars-visibility.php:377
254
  msgid "On any page of these types"
255
  msgstr ""
256
 
257
+ #: inc/class-custom-sidebars-visibility.php:395
258
  msgid "Only for specific %s"
259
  msgstr ""
260
 
261
+ #: inc/class-custom-sidebars-visibility.php:396
262
  msgid "Only these %s:"
263
  msgstr ""
264
 
269
  "\t\t\t\t\t\tto disable accessibility mode and use the %1$s plugin!"
270
  msgstr ""
271
 
272
+ #: inc/class-custom-sidebars.php:772
273
  msgid "Pro Version Features"
274
  msgstr ""
275
 
276
+ #: inc/class-custom-sidebars.php:944 views/import.php:140
277
+ msgid "Widgets"
278
+ msgstr ""
279
+
280
+ #: inc/class-custom-sidebars.php:954
281
+ msgid "Support"
282
+ msgstr ""
283
+
284
+ #: views/col-sidebars.php:18
285
  msgid "(Not available for Home-Page)"
286
  msgstr ""
287
 
288
+ #: views/col-sidebars.php:20
289
  msgid "(Not available for Blog-Page)"
290
  msgstr ""
291
 
292
+ #: views/import.php:60 views/widgets-export.php:33
293
  msgid "Import"
294
  msgstr ""
295
 
296
+ #: views/import.php:67
297
  msgid "Filename"
298
  msgstr ""
299
 
300
+ #: views/import.php:71
301
  msgid "Exported on"
302
  msgstr ""
303
 
304
+ #: views/import.php:77
305
  msgid "WordPress settings"
306
  msgstr ""
307
 
308
+ #: views/import.php:88
309
  msgid "WordPress version"
310
  msgstr ""
311
 
312
+ #: views/import.php:93
313
  msgid "Plugin version"
314
  msgstr ""
315
 
316
+ #: views/import.php:98
317
  msgid "Theme"
318
  msgstr ""
319
 
320
+ #: views/import.php:125
321
  msgid "Mark the sidebars that you want to import."
322
  msgstr ""
323
 
324
+ #: views/import.php:130
325
  msgid "Also import all widgets of the selected sidebars."
326
  msgstr ""
327
 
328
+ #: views/import.php:137 views/widgets-editor.php:15
329
  msgid "Name"
330
  msgstr ""
331
 
332
+ #: views/import.php:138 views/widgets-editor.php:20
333
  msgid "Description"
334
  msgstr ""
335
 
336
+ #: views/import.php:139
337
  msgid "Note"
338
  msgstr ""
339
 
340
+ #: views/import.php:147
341
+ msgid "New sidebar will be created"
342
  msgstr ""
343
 
344
+ #: views/import.php:149
345
  msgid "Existing sidebar will be replaced!"
346
  msgstr ""
347
 
348
+ #: views/import.php:205
 
 
 
 
349
  msgid "(Theme sidebar)"
350
  msgstr ""
351
 
352
+ #: views/import.php:233
353
  msgid "Configuration"
354
  msgstr ""
355
 
356
+ #: views/import.php:237
357
  msgid "Replaceable sidebars"
358
  msgstr ""
359
 
360
+ #: views/import.php:240
361
  msgid "Replaceable Sidebars"
362
  msgstr ""
363
 
364
+ #: views/import.php:250
365
  msgid "By post type"
366
  msgstr ""
367
 
368
+ #: views/import.php:263
369
  msgid "Post-type archives"
370
  msgstr ""
371
 
372
+ #: views/import.php:276
373
  msgid "By category"
374
  msgstr ""
375
 
376
+ #: views/import.php:289
377
  msgid "Category archives"
378
  msgstr ""
379
 
380
+ #: views/import.php:305
381
  msgid "Main blog page"
382
  msgstr ""
383
 
384
+ #: views/import.php:306
385
  msgid "Date archives"
386
  msgstr ""
387
 
388
+ #: views/import.php:307
389
  msgid "Author archives"
390
  msgstr ""
391
 
392
+ #: views/import.php:308
393
  msgid "Tag archives"
394
  msgstr ""
395
 
396
+ #: views/import.php:309
397
  msgid "Search results page"
398
  msgstr ""
399
 
400
+ #: views/import.php:319
401
  msgid "Replace the current plugin configuration with the imported configuration."
402
  msgstr ""
403
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: WPMUDEV, marquex, WPMUDEV-Support2, WPMUDEV-Support1, WPMUDEV-Supp
3
  Tags: custom sidebars, widgets, sidebars, custom, sidebar, widget, personalize
4
  Requires at least: 3.3
5
  Tested up to: 4.7.2
6
- Stable tag: 2.1.2.0
7
 
8
  Display custom widget configurations for every page or post on your site.
9
 
@@ -33,20 +33,21 @@ Every part of Custom Sidebars integrates seamlessly with the Widgets menu for si
33
  <li>Set custom widgets for individual posts and pages, categories, post types, and archives</li>
34
  <li>Seamless integration with the WordPress Widgets menu</li>
35
  <li>Works with well-coded themes and doesn't slow down your site</li>
 
 
 
 
36
  </ul>
37
 
38
  Install Custom Sidebars and see for yourself why it's the most popular widget extension plugin available for WordPress with over 200,000 downloads.
39
  <br>
40
  </blockquote>
41
 
42
- <h4>Need more control?</h4>
43
  <br>
44
- If you want more targeted controls checkout <a href="https://premium.wpmudev.org/project/custom-sidebars-pro/">Custom Sidebars Pro:</a>
45
  <ul>
46
- <li>Set individual widget visibility – for guests, by user role, by post type, for special pages or categories</li>
47
- <li>Author specific sidebars – display a custom sidebar for each of your authors</li>
48
- <li>Clone and sync widget settings – quickly edit complex configurations</li>
49
- <li>Import and export custom sidebars – backup and share sidebars</li>
50
  <li><a href="https://premium.wpmudev.org/support/">24/7 support</a> for all things WordPress</li>
51
  <li><a href="http://premium.wpmudev.org/join/">100+ premium plugins, themes, support, updates and services</a> – Including Hummingbird pagespeed booster, Uptime monitoring and security hardening</li>
52
  </ul>
@@ -75,7 +76,7 @@ There are two ways of installing the plugin:
75
 
76
  Once you have the plugin activated you will find all new features inside your "Widgets" screen! There you will be able to create and manage your own sidebars.
77
 
78
- Find more functionality and usage information on the [Custom Sidebars Pro page](https://premium.wpmudev.org/project/custom-sidebars-pro/).
79
 
80
  [youtube https://www.youtube.com/watch?v=q05O9OFEYHM]
81
 
@@ -105,10 +106,6 @@ You can create all the sidebars you want, but you need some sidebars of your the
105
 
106
  Any user that can switch themes, can create sidebars. Switch_themes is the capability needed to manage widgets, so if you can’t edit widgets you can’t create custom sidebars. There are some plugins to give capabilities to the roles, so you can make your author be able to create the sidebars. Try [User role editor](http://wordpress.org/extend/plugins/user-role-editor/)
107
 
108
- = Does it have custom taxonomies support? =
109
-
110
- This plugin supports showing your posts on all different categories or tags, it's awesome, for more visibility controls try <a href="https://premium.wpmudev.org/project/custom-sidebars-pro/">Custom Sidebars Pro</a>
111
-
112
  = Can I use the plugin in commercial projects? =
113
 
114
  Custom Sidebars has the same license as WordPress, so you can use it wherever you want for free. Yay!
@@ -194,162 +191,162 @@ If you are running a earlier version of WordPress download Custom Sidebars 0.8.2
194
  * New: Assign a Sidebar to 404 pages via the Sidebar Location dialog.
195
 
196
  = 2.0.9.6 =
197
- * Fix: In some browsers the "Add sidebar" popup was partially hidden.
198
- * Fix: Sometimes the dropdown list of a multiselect list stayed open.
199
- * Fix: Plugin now correctly loads the .po files to translate to other languages.
200
- * Some other small improvements.
201
 
202
  = 2.0.9.4 =
203
- * Fix: For some users the plugin was not loading anymore after updating to 2.0.9.1.
204
 
205
  = 2.0.9.3 =
206
- * Fix: Z-index issue in Dashboard where wide widgets where covered by the main-menu.
207
- * Fix: Added compatibility for static front-page sidebars with version 2.0.9
208
 
209
  = 2.0.9.2 =
210
- * Fix: Sidebar Locations "Front Page" and "Post Index" now work correctly.
211
 
212
  = 2.0.9.1 =
213
- * Fix: Sidebars now support unicode-text in name/description.
214
- * Minor: New debugging output that explains why a sidebar/widget is displayed.
215
 
216
 
217
  = 2.0.9 =
218
- * Fix: Fixed issue with WP sidebar chooser right after creating a new sidebar.
219
- * Fix: Fixed various issues when flagging a sidebar s replaceable.
220
- * Fix: Plugin will not load in accessibility mode but display a notice instead.
221
- * Minor fix: Make code compatible with PHP 5.2.4
222
- * Minor fix: Slight improvement of AJAX stability
223
- * Minor fix: Plugin now requires capability "edit_theme_options"
224
 
225
  = 2.0.8 =
226
- * Fix: Fixed issue with settings not being saved correctly.
227
 
228
  = 2.0.7 =
229
- * Fix: Fixed issue with some people losing some sidebar settings after update.
230
 
231
  = 2.0.6.1 =
232
- * Minor fix: Use WordPress core functions to get URL to JavaScript files.
233
- * Minor fix: Refactor function name to avoid misunderstandings.
234
 
235
  = 2.0.5 =
236
- * Fixed: Meta box in post editor did show missing sidebars (e.g. after switching the theme)
237
- * Fixed: PHP warning about strict standards.
238
 
239
  = 2.0.3 =
240
- * Fixed: JavaScript errors on Windows servers are fixed.
241
 
242
  = 2.0.2 =
243
- * Fixed: Dashboard notification is now removed when clicking "dismiss"
244
 
245
  = 2.0.1 =
246
- * PHP 5.2 compatibility layer.
247
 
248
  = 2.0 =
249
- * Complete UI redesign!
250
- * Many small bugfixes.
251
 
252
  = 1.6 =
253
- * Added: WordPress filter "cs_sidebar_params" is called before a custom sidebar is registered.
254
- * Added: Add setting "CUSTOM_SIDEBAR_DISABLE_METABOXES" in wp-config.php to remove custom-sidebar meta boxes.
255
 
256
  = 1.5 =
257
- * Added: Custom sidebars now works with BuddyPress pages.
258
 
259
  = 1.4 =
260
- * Fixed: Individual post sidebar selection when default sidebars for single posts are defined
261
- * Fixed: Category sidebars sorting
262
- * Added: WP 3.8 new admin design (MP6) support
263
 
264
  = 1.3.1 =
265
- * Fixed: Absolute paths that leaded to the outdated browser error
266
- * Fixed: Stripped slashes for the pre/post widget/title fields
267
 
268
  = 1.3 =
269
- * Fixed: A lot of warnings with the PHP debug mode on
270
- * Improved: Styles to make them compatible with WP 3.6
271
- * Fixed: Creation of sidebars from the custom sidebars option
272
- * Fixed: Missing loading icons in the admin area
273
- * Removed: Donate banner. Thanks to the ones that have be supporting Custom Sidebar so far.
274
 
275
  = 1.2 =
276
- * Fixed: Searches with no results shows default sidebar.
277
- * Added: RTL support (thanks to Dvir http://foxy.co.il/blog/)
278
- * Improved: Minor enhancements in the interface to adapt it to wp3.
279
- * Added: French and Hebrew translations
280
- * Fixed: Slashes are added to the attributes of before and after title/widget
281
 
282
  = 1.1 =
283
- * Fixed: Where lightbox not showing for everybody (Thanks to Robert Utnehmer)
284
- * Added: Default sidebar for search results pages
285
- * Added: Default sidebar for date archives
286
- * Added: Default sidebar for Uncategorized posts
287
 
288
  = 1.0 =
289
- * Fixed: Special characters make sidebars undeletable
290
- * Added: Child/parent pages support
291
- * Improved interface to handle hundreds of sidebars easily
292
- * Added: Ajax support for creating an editing sidebars from the widget page
293
- * Added: Italian translation
294
 
295
  = 0.8.2 =
296
- * Fixed: Problems with Spanish translation
297
- * Added: Dutch and German language files
298
- * Fixed: Some CSS issues with WP3.3
299
 
300
  = 0.8.1 =
301
- * Fixed: You can assign sidebars to your pages again.
302
 
303
  = 0.8 =
304
- * Fixed: Category hierarchy is now handled properly by the custom sidebars plugin.
305
- * Added: Sidebars can be set for every custom post type post individually.
306
- * Improved the way it replace the sidebars.
307
- * Improved some text and messages in the back-end.
308
 
309
  = 0.7.1 =
310
- * Fixed: Now the plugin works with themes like Thesis that don't use the the_header hook. Changed the hook where execute the replacement code to wp_head.
311
- * Fixed: When a second sidebar is replaced with the originally first sidebar, it is replaced by the first sidebar replacement instead.
312
 
313
  = 0.7 =
314
- * Fixed: Bulk and Quick editing posts and pages reset their custom sidebars.
315
- * Changed capability needed to switch_themes, and improved capability management.
316
 
317
  = 0.6 =
318
 
319
- * New interface, more user friendly
320
- * Added the possibility of customize the main blog page sidebars
321
- * Added the sidebars by category, so now you can personalize all the post that belongs to a category easily in a hierarchical way
322
- * Added the possibility of customize the authors page sidebars
323
- * Added the possibility of customize the tags page sidebars
324
- * Added, now it is possible to edit the sidebars names, as well as the pre-widget, post-widget, pre-title, post-title for a sidebar.
325
- * Added the possibility of customize the sidebars of posts list by category or post-type.
326
 
327
 
328
  = 0.5 =
329
 
330
- * Fixed a bug that didn't allow to create new bars when every previous bars were deleted.
331
- * Fixed a bug introduced in v0.4 that did not allow to assign bars per post-types properly
332
- * Added an option to remove all the Custom Sidebars data from the database easily.
333
 
334
  = 0.4 =
335
 
336
- * Empty sidebars will now be shown as empty, instead of displaying the theme's default sidebar.
337
 
338
  = 0.3 =
339
 
340
- * PHP 4 Compatible (Thanks to Kay Larmer)
341
- * Fixed a bug introduced in v0.2 that did not allow to save the replaceable bars options
342
 
343
  = 0.2 =
344
 
345
- * Improved security by adding wp_nonces to the forms.
346
- * Added the pt-widget post type to the ignored post types.
347
- * Improved i18n files.
348
- * Fixed screenshots for documentation.
349
 
350
  = 0.1 =
351
 
352
- * Initial release
353
 
354
  == Upgrade Notice ==
355
 
3
  Tags: custom sidebars, widgets, sidebars, custom, sidebar, widget, personalize
4
  Requires at least: 3.3
5
  Tested up to: 4.7.2
6
+ Stable tag: 3.0.0.0
7
 
8
  Display custom widget configurations for every page or post on your site.
9
 
33
  <li>Set custom widgets for individual posts and pages, categories, post types, and archives</li>
34
  <li>Seamless integration with the WordPress Widgets menu</li>
35
  <li>Works with well-coded themes and doesn't slow down your site</li>
36
+ <li>Set individual widget visibility – for guests, by user role, by post type, for special pages or categories</li>
37
+ <li>Author specific sidebars – display a custom sidebar for each of your authors</li>
38
+ <li>Clone and sync widget settings – quickly edit complex configurations</li>
39
+ <li>Import and export custom sidebars – backup and share sidebars</li>
40
  </ul>
41
 
42
  Install Custom Sidebars and see for yourself why it's the most popular widget extension plugin available for WordPress with over 200,000 downloads.
43
  <br>
44
  </blockquote>
45
 
46
+ <h4>Need more?</h4>
47
  <br>
48
+ If you want more checkout <a href="https://premium.wpmudev.org/project/custom-sidebars-pro/">Custom Sidebars Pro:</a>
49
  <ul>
50
+ <li>Free of ads</li>
 
 
 
51
  <li><a href="https://premium.wpmudev.org/support/">24/7 support</a> for all things WordPress</li>
52
  <li><a href="http://premium.wpmudev.org/join/">100+ premium plugins, themes, support, updates and services</a> – Including Hummingbird pagespeed booster, Uptime monitoring and security hardening</li>
53
  </ul>
76
 
77
  Once you have the plugin activated you will find all new features inside your "Widgets" screen! There you will be able to create and manage your own sidebars.
78
 
79
+ Find more usage information on the [Custom Sidebars Pro page](https://premium.wpmudev.org/project/custom-sidebars-pro/).
80
 
81
  [youtube https://www.youtube.com/watch?v=q05O9OFEYHM]
82
 
106
 
107
  Any user that can switch themes, can create sidebars. Switch_themes is the capability needed to manage widgets, so if you can’t edit widgets you can’t create custom sidebars. There are some plugins to give capabilities to the roles, so you can make your author be able to create the sidebars. Try [User role editor](http://wordpress.org/extend/plugins/user-role-editor/)
108
 
 
 
 
 
109
  = Can I use the plugin in commercial projects? =
110
 
111
  Custom Sidebars has the same license as WordPress, so you can use it wherever you want for free. Yay!
191
  * New: Assign a Sidebar to 404 pages via the Sidebar Location dialog.
192
 
193
  = 2.0.9.6 =
194
+ * Fix: In some browsers the "Add sidebar" popup was partially hidden.
195
+ * Fix: Sometimes the dropdown list of a multiselect list stayed open.
196
+ * Fix: Plugin now correctly loads the .po files to translate to other languages.
197
+ * Some other small improvements.
198
 
199
  = 2.0.9.4 =
200
+ * Fix: For some users the plugin was not loading anymore after updating to 2.0.9.1.
201
 
202
  = 2.0.9.3 =
203
+ * Fix: Z-index issue in Dashboard where wide widgets where covered by the main-menu.
204
+ * Fix: Added compatibility for static front-page sidebars with version 2.0.9
205
 
206
  = 2.0.9.2 =
207
+ * Fix: Sidebar Locations "Front Page" and "Post Index" now work correctly.
208
 
209
  = 2.0.9.1 =
210
+ * Fix: Sidebars now support unicode-text in name/description.
211
+ * Minor: New debugging output that explains why a sidebar/widget is displayed.
212
 
213
 
214
  = 2.0.9 =
215
+ * Fix: Fixed issue with WP sidebar chooser right after creating a new sidebar.
216
+ * Fix: Fixed various issues when flagging a sidebar s replaceable.
217
+ * Fix: Plugin will not load in accessibility mode but display a notice instead.
218
+ * Minor fix: Make code compatible with PHP 5.2.4
219
+ * Minor fix: Slight improvement of AJAX stability
220
+ * Minor fix: Plugin now requires capability "edit_theme_options"
221
 
222
  = 2.0.8 =
223
+ * Fix: Fixed issue with settings not being saved correctly.
224
 
225
  = 2.0.7 =
226
+ * Fix: Fixed issue with some people losing some sidebar settings after update.
227
 
228
  = 2.0.6.1 =
229
+ * Minor fix: Use WordPress core functions to get URL to JavaScript files.
230
+ * Minor fix: Refactor function name to avoid misunderstandings.
231
 
232
  = 2.0.5 =
233
+ * Fixed: Meta box in post editor did show missing sidebars (e.g. after switching the theme)
234
+ * Fixed: PHP warning about strict standards.
235
 
236
  = 2.0.3 =
237
+ * Fixed: JavaScript errors on Windows servers are fixed.
238
 
239
  = 2.0.2 =
240
+ * Fixed: Dashboard notification is now removed when clicking "dismiss"
241
 
242
  = 2.0.1 =
243
+ * PHP 5.2 compatibility layer.
244
 
245
  = 2.0 =
246
+ * Complete UI redesign!
247
+ * Many small bugfixes.
248
 
249
  = 1.6 =
250
+ * Added: WordPress filter "cs_sidebar_params" is called before a custom sidebar is registered.
251
+ * Added: Add setting "CUSTOM_SIDEBAR_DISABLE_METABOXES" in wp-config.php to remove custom-sidebar meta boxes.
252
 
253
  = 1.5 =
254
+ * Added: Custom sidebars now works with BuddyPress pages.
255
 
256
  = 1.4 =
257
+ * Fixed: Individual post sidebar selection when default sidebars for single posts are defined
258
+ * Fixed: Category sidebars sorting
259
+ * Added: WP 3.8 new admin design (MP6) support
260
 
261
  = 1.3.1 =
262
+ * Fixed: Absolute paths that leaded to the outdated browser error
263
+ * Fixed: Stripped slashes for the pre/post widget/title fields
264
 
265
  = 1.3 =
266
+ * Fixed: A lot of warnings with the PHP debug mode on
267
+ * Improved: Styles to make them compatible with WP 3.6
268
+ * Fixed: Creation of sidebars from the custom sidebars option
269
+ * Fixed: Missing loading icons in the admin area
270
+ * Removed: Donate banner. Thanks to the ones that have be supporting Custom Sidebar so far.
271
 
272
  = 1.2 =
273
+ * Fixed: Searches with no results shows default sidebar.
274
+ * Added: RTL support (thanks to Dvir http://foxy.co.il/blog/)
275
+ * Improved: Minor enhancements in the interface to adapt it to wp3.
276
+ * Added: French and Hebrew translations
277
+ * Fixed: Slashes are added to the attributes of before and after title/widget
278
 
279
  = 1.1 =
280
+ * Fixed: Where lightbox not showing for everybody (Thanks to Robert Utnehmer)
281
+ * Added: Default sidebar for search results pages
282
+ * Added: Default sidebar for date archives
283
+ * Added: Default sidebar for Uncategorized posts
284
 
285
  = 1.0 =
286
+ * Fixed: Special characters make sidebars undeletable
287
+ * Added: Child/parent pages support
288
+ * Improved interface to handle hundreds of sidebars easily
289
+ * Added: Ajax support for creating an editing sidebars from the widget page
290
+ * Added: Italian translation
291
 
292
  = 0.8.2 =
293
+ * Fixed: Problems with Spanish translation
294
+ * Added: Dutch and German language files
295
+ * Fixed: Some CSS issues with WP3.3
296
 
297
  = 0.8.1 =
298
+ * Fixed: You can assign sidebars to your pages again.
299
 
300
  = 0.8 =
301
+ * Fixed: Category hierarchy is now handled properly by the custom sidebars plugin.
302
+ * Added: Sidebars can be set for every custom post type post individually.
303
+ * Improved the way it replace the sidebars.
304
+ * Improved some text and messages in the back-end.
305
 
306
  = 0.7.1 =
307
+ * Fixed: Now the plugin works with themes like Thesis that don't use the the_header hook. Changed the hook where execute the replacement code to wp_head.
308
+ * Fixed: When a second sidebar is replaced with the originally first sidebar, it is replaced by the first sidebar replacement instead.
309
 
310
  = 0.7 =
311
+ * Fixed: Bulk and Quick editing posts and pages reset their custom sidebars.
312
+ * Changed capability needed to switch_themes, and improved capability management.
313
 
314
  = 0.6 =
315
 
316
+ * New interface, more user friendly
317
+ * Added the possibility of customize the main blog page sidebars
318
+ * Added the sidebars by category, so now you can personalize all the post that belongs to a category easily in a hierarchical way
319
+ * Added the possibility of customize the authors page sidebars
320
+ * Added the possibility of customize the tags page sidebars
321
+ * Added, now it is possible to edit the sidebars names, as well as the pre-widget, post-widget, pre-title, post-title for a sidebar.
322
+ * Added the possibility of customize the sidebars of posts list by category or post-type.
323
 
324
 
325
  = 0.5 =
326
 
327
+ * Fixed a bug that didn't allow to create new bars when every previous bars were deleted.
328
+ * Fixed a bug introduced in v0.4 that did not allow to assign bars per post-types properly
329
+ * Added an option to remove all the Custom Sidebars data from the database easily.
330
 
331
  = 0.4 =
332
 
333
+ * Empty sidebars will now be shown as empty, instead of displaying the theme's default sidebar.
334
 
335
  = 0.3 =
336
 
337
+ * PHP 4 Compatible (Thanks to Kay Larmer)
338
+ * Fixed a bug introduced in v0.2 that did not allow to save the replaceable bars options
339
 
340
  = 0.2 =
341
 
342
+ * Improved security by adding wp_nonces to the forms.
343
+ * Added the pt-widget post type to the ignored post types.
344
+ * Improved i18n files.
345
+ * Fixed screenshots for documentation.
346
 
347
  = 0.1 =
348
 
349
+ * Initial release
350
 
351
  == Upgrade Notice ==
352
 
views/col-sidebars.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Custom column inside the post-list.
4
+ *
5
+ * Uses:
6
+ * $selected
7
+ * $wp_registered_sidebars
8
+ * $post_id
9
+ */
10
+
11
+ $sidebars = CustomSidebars::get_options( 'modifiable' );
12
+
13
+ $is_front = get_option( 'page_on_front' ) == $post_id;
14
+ $is_blog = get_option( 'page_for_posts' ) == $post_id;
15
+
16
+ if ( $is_front || $is_blog ) {
17
+ if ( $is_front ) {
18
+ _e( '(Not available for Home-Page)', 'custom-sidebars' );
19
+ } else {
20
+ _e( '(Not available for Blog-Page)', 'custom-sidebars' );
21
+ }
22
+ foreach ( $sidebars as $s ) : ?>
23
+ <span data-sidebar="<?php echo esc_attr( $s ); ?>" data-replaced="<?php echo esc_attr( @$selected[ $s ] ); ?>" data-cshide="yes">
24
+ <?php endforeach;
25
+ } else {
26
+ global $wp_registered_sidebars;
27
+ $available = CustomSidebars::sort_sidebars_by_name( $wp_registered_sidebars );
28
+ foreach ( $sidebars as $s ) {
29
+ $sb_name = $available[ $s ]['name'];
30
+ $replaced = ! empty( $available[ $selected[ $s ] ] );
31
+ $class = $replaced ? 'cust' : 'def';
32
+
33
+ ?>
34
+ <div class="<?php echo esc_attr( $class, 'custom-sidebars' ); ?>"
35
+ data-sidebar="<?php echo esc_attr( $s ); ?>"
36
+ data-replaced="<?php echo esc_attr( @$selected[ $s ] ); ?>">
37
+ <small class="cs-key">
38
+ <?php echo esc_html( $sb_name ); ?>
39
+ </small>
40
+ <span class="cs-val">
41
+ <?php if ( $replaced ) : ?>
42
+ <?php echo esc_html( $available[ $selected[ $s ] ]['name'] ); ?>
43
+ <?php else : ?>
44
+ -
45
+ <?php endif; ?>
46
+ </span>
47
+ </div>
48
+ <?php
49
+ }
50
+ }
views/import.php ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PRO section: Show interface for import preview.
4
+ */
5
+
6
+ global $wp_version;
7
+
8
+ $import = CustomSidebarsExport::get_import_data();
9
+
10
+ $date_format = get_option( 'date_format' ) . ', ' . get_option( 'time_format' );
11
+ $theme = wp_get_theme();
12
+ $current_sidebars = CustomSidebars::get_custom_sidebars();
13
+ $theme_sidebars = CustomSidebars::get_sidebars();
14
+ $current_keys = array();
15
+ foreach ( $current_sidebars as $c_sidebar ) {
16
+ $current_keys[] = $c_sidebar['id'];
17
+ }
18
+
19
+ $csb_info = get_plugin_data( CSB_PLUGIN );
20
+
21
+ /**
22
+ * Helper function used only in this view.
23
+ * It renders a list with sidebar-replacement details
24
+ */
25
+ function list_sidebar_replacement( $label, $list ) {
26
+ $import = CustomSidebarsExport::get_import_data();
27
+ $theme_sidebars = CustomSidebars::get_sidebars();
28
+
29
+ if ( is_array( $list ) ) {
30
+ foreach ( $list as $from_id => $to_id ) {
31
+ $from = $theme_sidebars[ $from_id ];
32
+ $to = array();
33
+ if ( isset( $theme_sidebars[ $to_id ] ) ) {
34
+ $to = $theme_sidebars[ $to_id ];
35
+ } else {
36
+ $to = $import['sidebars'][ $to_id ];
37
+ }
38
+ ?>
39
+ <tr>
40
+ <th scope="row"><?php echo esc_html( $label ); ?></th>
41
+ <td><?php echo esc_html( $from['name'] ); ?></td>
42
+ <td><i class="dashicons dashicons-arrow-right-alt hint"></i></td>
43
+ <td><?php echo esc_html( $to['name'] ); ?></td>
44
+ </tr>
45
+ <?php
46
+ }
47
+ }
48
+ }
49
+ ?>
50
+ <div>
51
+ <div class="wpmui-form">
52
+ <?php if ( ! empty( $import ) ) : ?>
53
+ <?php
54
+ /* *****************************************************************
55
+ *
56
+ * Show basic infos about the WordPress configuration at time of
57
+ * the export.
58
+ */
59
+ ?>
60
+ <h2 class="no-pad-top"><?php _e( 'Import', 'custom-sidebars' ); ?></h2>
61
+ <div class="show-infos">
62
+ <i class="dashicons dashicons-info"></i>
63
+ <div class="export-infos" style="display:none">
64
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
65
+ <tbody>
66
+ <tr>
67
+ <th><?php _e( 'Filename', 'custom-sidebars' ); ?></th>
68
+ <td colspan="2"><?php echo esc_html( @$import['meta']['filename'] ); ?></td>
69
+ </tr>
70
+ <tr>
71
+ <th><?php _e( 'Exported on', 'custom-sidebars' ); ?></th>
72
+ <td colspan="2"><?php echo esc_html( ' ' . date( $date_format, $import['meta']['created'] ) ); ?></td>
73
+ </tr>
74
+ </tbody>
75
+ </table>
76
+
77
+ <div class="section"><?php _e( 'WordPress settings', 'custom-sidebars' ); ?></div>
78
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
79
+ <thead>
80
+ <tr>
81
+ <th></th>
82
+ <td>Export</td>
83
+ <td>Current</td>
84
+ </tr>
85
+ </thead>
86
+ <tbody>
87
+ <tr>
88
+ <th><?php _e( 'WordPress version', 'custom-sidebars' ); ?></th>
89
+ <td><?php echo esc_html( $import['meta']['wp_version'] ); ?></td>
90
+ <td><?php echo esc_html( $wp_version ); ?></td>
91
+ </tr>
92
+ <tr>
93
+ <th><?php _e( 'Plugin version', 'custom-sidebars' ); ?></th>
94
+ <td><?php echo esc_html( $import['meta']['csb_version'] ); ?></td>
95
+ <td><?php echo esc_html( @$csb_info['Version'] ); ?></td>
96
+ </tr>
97
+ <tr>
98
+ <th><?php _e( 'Theme', 'custom-sidebars' ); ?></th>
99
+ <td><?php echo esc_html( $import['meta']['theme_name'] . ' (' . $import['meta']['theme_version'] . ')' ); ?></td>
100
+ <td><?php echo esc_html( $theme->get( 'Name' ) . ' (' . $theme->get( 'Version' ) . ')' ); ?></td>
101
+ </tr>
102
+ </tbody>
103
+ </table>
104
+ </div>
105
+ </div>
106
+
107
+ <?php if ( ! empty( $import['meta']['description'] ) ) : ?>
108
+ <pre><?php echo esc_html( stripslashes( $import['meta']['description'] ) ); ?></pre>
109
+ <?php endif; ?>
110
+
111
+
112
+ <form class="frm-import csb-form">
113
+ <input type="hidden" name="do" value="import" />
114
+
115
+
116
+ <?php
117
+ /* *****************************************************************
118
+ *
119
+ * List all sidebars in the import file
120
+ */
121
+ $alternate = '';
122
+ ?>
123
+ <h3 class="title"><?php _e( 'Custom Sidebars', 'custom-sidebars' ); ?></h3>
124
+ <p>
125
+ <?php _e( 'Mark the sidebars that you want to import.', 'custom-sidebars' ); ?>
126
+ </p>
127
+ <p>
128
+ <label for="import-widgets">
129
+ <input type="checkbox" id="import-widgets" name="import_widgets" />
130
+ <?php _e( 'Also import all widgets of the selected sidebars.', 'custom-sidebars' ); ?>
131
+ </label>
132
+ </p>
133
+ <table class="widefat">
134
+ <thead>
135
+ <tr>
136
+ <th scope="col" id="cb" class="manage-column column-cb check-column"><input type="checkbox" /></th>
137
+ <th scope="col" id="name" class="manage-column column-name"><?php _e( 'Name', 'custom-sidebars' ); ?></th>
138
+ <th scope="col" id="description" class="manage-column column-description"><?php _e( 'Description', 'custom-sidebars' ); ?></th>
139
+ <th scope="col" id="note" class="manage-column column-note"><?php _e( 'Note', 'custom-sidebars' ); ?></th>
140
+ <th scope="col" id="widgets" class="manage-column column-widgets" style="display:none"><?php _e( 'Widgets', 'custom-sidebars' ); ?></th>
141
+ </tr>
142
+ </thead>
143
+ <tbody>
144
+ <?php
145
+ foreach ( $import['sidebars'] as $sidebar ) {
146
+ $alternate = ('' == $alternate ? 'alternate' : '');
147
+ $note = __( 'New sidebar will be created', 'custom-sidebars' );
148
+ if ( in_array( $sidebar['id'], $current_keys ) ) {
149
+ $note = __( 'Existing sidebar will be replaced!', 'custom-sidebars' );
150
+ }
151
+ $import_sidebar = @$import['widgets'][ $sidebar['id'] ];
152
+ if ( ! is_array( $import_sidebar ) ) {
153
+ $import_sidebar = array();
154
+ }
155
+ $id = sprintf( 'import_sb_id_%s', $sidebar['id'] );
156
+ ?>
157
+ <tr class="<?php echo esc_attr( $alternate ); ?>">
158
+ <th scope="row" class="check-column">
159
+ <input type="checkbox" name="import_sb_<?php echo esc_attr( $sidebar['id'] ); ?>" id="<?php echo esc_attr( $id ); ?>"/>
160
+ </th>
161
+ <td class="name column-name"><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $sidebar['name'] ); ?></label></td>
162
+ <td class="description column-description"><?php echo esc_html( $sidebar['description'] ); ?></td>
163
+ <td class="note column-note"><?php echo esc_html( $note ); ?></td>
164
+ <td class="widgets column-widgets" style="display:none">
165
+ <?php
166
+ if ( count( $import_sidebar ) ) {
167
+ echo '<ul>';
168
+ foreach ( $import_sidebar as $key => $data ) {
169
+ printf( '<li>%s</li>', esc_html( $data['name'] ) );
170
+ }
171
+ echo '</ul>';
172
+ } else {
173
+ echo '-';
174
+ }
175
+ ?>
176
+ </td>
177
+ </tr>
178
+ <?php
179
+ }
180
+
181
+
182
+ /* *****************************************************************
183
+ *
184
+ * List all default theme sidebars that exist in the import file
185
+ */
186
+
187
+ foreach ( $theme_sidebars as $sidebar ) {
188
+ if ( isset( $import['widgets'][ $sidebar['id'] ] ) ) {
189
+ $alternate = ('' == $alternate ? 'alternate' : '');
190
+ $import_sidebar = @$import['widgets'][ $sidebar['id'] ];
191
+ if ( ! is_array( $import_sidebar ) ) {
192
+ $import_sidebar = array();
193
+ }
194
+ if ( ! count( $import_sidebar ) ) {
195
+ continue;
196
+ }
197
+ $id = sprintf( 'import_sb_id_%s', $sidebar['id'] );
198
+ ?>
199
+ <tr class="import-widgets <?php echo esc_attr( $alternate ); ?>" style="display: none">
200
+ <th scope="row" class="check-column">
201
+ <input type="checkbox" name="import_sb_<?php echo esc_attr( $sidebar['id'] ); ?>" id="<?php echo esc_attr( $id ); ?>"/>
202
+ </th>
203
+ <td class="name column-name"><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $sidebar['name'] ); ?></label></td>
204
+ <td class="description column-description"><?php echo esc_html( $sidebar['description'] ); ?></td>
205
+ <td><em><?php _e( '(Theme sidebar)', 'custom-sidebars' ); ?></em></td>
206
+ <td class="widgets column-widgets">
207
+ <?php
208
+ if ( count( $import_sidebar ) ) {
209
+ echo '<ul>';
210
+ foreach ( $import_sidebar as $key => $data ) {
211
+ printf( '<li>%s</li>', esc_html( $data['name'] ) );
212
+ }
213
+ echo '</ul>';
214
+ } else {
215
+ echo '-';
216
+ }
217
+ ?>
218
+ </td>
219
+ </tr>
220
+ <?php
221
+ }
222
+ }
223
+ ?>
224
+ </tbody>
225
+ </table>
226
+ <?php
227
+ /* *****************************************************************
228
+ *
229
+ * Show the custom sidebar configuration
230
+ */
231
+ ?>
232
+ <p>&nbsp;</p>
233
+ <h3 class="title"><?php _e( 'Configuration', 'custom-sidebars' ); ?>
234
+ <div class="show-infos">
235
+ <i class="dashicons dashicons-info"></i>
236
+ <div class="export-infos" style="display:none">
237
+ <div class="section"><?php _e( 'Replaceable sidebars', 'custom-sidebars' ); ?></div>
238
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
239
+ <tr>
240
+ <th scope="row"><?php _e( 'Replaceable Sidebars', 'custom-sidebars' ); ?></th>
241
+ <td>
242
+ <?php foreach ( $import['options']['modifiable'] as $sb_id ) : ?>
243
+ <?php echo esc_html( $theme_sidebars[ $sb_id ]['name'] ); ?><br />
244
+ <?php endforeach; ?>
245
+ </td>
246
+ </tr>
247
+ </table>
248
+
249
+ <?php /* single-posttype */ ?>
250
+ <div class="section"><?php _e( 'By post type', 'custom-sidebars' ); ?></div>
251
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
252
+ <?php
253
+ $list = @$import['options']['post_type_single'];
254
+ foreach ( $list as $key => $values ) {
255
+ $type = get_post_type_object( $key );
256
+ if ( ! count( $values ) ) { continue; }
257
+ list_sidebar_replacement( $type->labels->name, $values );
258
+ }
259
+ ?>
260
+ </table>
261
+
262
+ <?php /* archive-posttype */ ?>
263
+ <div class="section"><?php _e( 'Post-type archives', 'custom-sidebars' ); ?></div>
264
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
265
+ <?php
266
+ $list = @$import['options']['post_type_archive'];
267
+ foreach ( $list as $key => $values ) {
268
+ $type = get_post_type_object( $key );
269
+ if ( ! count( $values ) ) { continue; }
270
+ list_sidebar_replacement( $type->labels->name, $values );
271
+ }
272
+ ?>
273
+ </table>
274
+
275
+ <?php /* single-category */ ?>
276
+ <div class="section"><?php _e( 'By category', 'custom-sidebars' ); ?></div>
277
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
278
+ <?php
279
+ $list = @$import['options']['category_single'];
280
+ foreach ( $list as $key => $values ) {
281
+ $cat = get_category( $key );
282
+ if ( ! count( $values ) ) { continue; }
283
+ list_sidebar_replacement( $cat->name, $values );
284
+ }
285
+ ?>
286
+ </table>
287
+
288
+ <?php /* archive-category */ ?>
289
+ <div class="section"><?php _e( 'Category archives', 'custom-sidebars' ); ?></div>
290
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
291
+ <?php
292
+ $list = @$import['options']['category_archive'];
293
+ foreach ( $list as $key => $values ) {
294
+ $cat = get_category( $key );
295
+ if ( ! count( $values ) ) { continue; }
296
+ list_sidebar_replacement( $cat->name, $values );
297
+ }
298
+ ?>
299
+ </table>
300
+
301
+ <?php /* special pages */ ?>
302
+ <div class="section"><?php _e( 'Special pages', 'custom-sidebars' ); ?></div>
303
+ <table cellspacing="1" cellpadding="4" class="csb-export-head">
304
+ <?php
305
+ list_sidebar_replacement( __( 'Main blog page', 'custom-sidebars' ), $import['options']['blog'] );
306
+ list_sidebar_replacement( __( 'Date archives', 'custom-sidebars' ), $import['options']['date'] );
307
+ list_sidebar_replacement( __( 'Author archives', 'custom-sidebars' ), $import['options']['authors'] );
308
+ list_sidebar_replacement( __( 'Tag archives', 'custom-sidebars' ), $import['options']['tags'] );
309
+ list_sidebar_replacement( __( 'Search results page', 'custom-sidebars' ), $import['options']['search'] );
310
+ ?>
311
+ </table>
312
+ </div>
313
+ </div>
314
+ </h3>
315
+
316
+ <p>
317
+ <label for="import-config">
318
+ <input type="checkbox" id="import-config" name="import_plugin_config" />
319
+ <?php _e( 'Replace the current plugin configuration with the imported configuration.', 'custom-sidebars' ); ?>
320
+ </label>
321
+ </p>
322
+
323
+ <input type="hidden" name="import_data" value="<?php echo esc_attr( base64_encode( json_encode( (object) $import ) ) ); ?>" />
324
+ <p class="buttons">
325
+ <button type="button" class="btn-cancel button-link">Cancel</button>
326
+ <button class="button-primary btn-import"><i class="dashicons dashicons-migrate"></i> Import selected items</button>
327
+ </p>
328
+ </form>
329
+
330
+ <?php endif; ?>
331
+ </div>
332
+ </div>
views/quick-edit.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Form displayed in the Quick Edit box of the post list.
4
+ *
5
+ * Uses:
6
+ * $selected
7
+ */
8
+
9
+ global $wp_registered_sidebars;
10
+ $available = CustomSidebars::sort_sidebars_by_name( $wp_registered_sidebars );
11
+
12
+ $sidebars = CustomSidebars::get_options( 'modifiable' );
13
+
14
+ ?>
15
+ <fieldset class="inline-edit-col-left cs-quickedit">
16
+ <div class="inline-edit-col">
17
+ <?php
18
+
19
+
20
+ foreach ( $sidebars as $s ) {
21
+ $sb_name = $available[ $s ]['name'];
22
+ ?>
23
+ <div class="inline-edit-group">
24
+ <label>
25
+ <span class="title"><?php echo esc_html( $sb_name ); ?></span>
26
+ <select name="cs_replacement_<?php echo esc_attr( $s ); ?>"
27
+ class="cs-replacement-field <?php echo esc_attr( $s ); ?>">
28
+ <option value=""></option>
29
+ <?php foreach ( $available as $a ) : ?>
30
+ <option value="<?php echo esc_attr( $a['id'] ); ?>" <?php selected( $selected[ $s ], $a['id'] ); ?>>
31
+ <?php echo esc_html( $a['name'] ); ?>
32
+ </option>
33
+ <?php endforeach; ?>
34
+ </select>
35
+ </label>
36
+ </div>
37
+ <?php
38
+ }
39
+
40
+ ?>
41
+ </div>
42
+ </fieldset>