Widget Context - Version 0.8

Version Description

Major code rewrite and refactoring to improve plugin performance and usability.

Download this release

Release Info

Developer kasparsd
Plugin Icon 128x128 Widget Context
Version 0.8
Comparing to
See all releases

Code changes from version 0.7.2 to 0.8

Files changed (4) hide show
  1. admin-style.css +12 -26
  2. readme.txt +58 -16
  3. screenshot-1.png +0 -0
  4. widget-context.php +232 -459
admin-style.css CHANGED
@@ -1,39 +1,25 @@
1
- .widget-context, .wl-visibility label { -moz-border-radius:0.5em; -webkit-border-radius:0.5em; }
2
- .widget-context-inside { -moz-border-radius:0.25em; -webkit-border-radius:0.25em; }
3
 
4
- .widget-context { width:64em; float:right; clear:both; margin-bottom:1em; background:#fff; }
5
- .widget-context-inside { background-color:#fff; float:left; clear:both; padding:1em 2em 1em 1em; border:1px solid #ccc; border-top-width:thick; margin:1em 0 1em 1em; }
6
- .widget-context h5 { font-size:1.1em; margin:0; float:left; }
7
- .widget-context .wl-header { float:left; width:100%; clear:both; margin-bottom:1em; border-bottom:2px solid #ccc; }
8
- .widget-context .wl-wrap-columns { float:left; width:100%; clear:both; }
9
 
10
- .wl-columns { float:left; width:35%; padding-top:0.5em; }
11
  .wl-columns input { vertical-align:middle; }
12
- .wl-column-2-1 { float:left; width:47%; }
13
- .wl-column-2-2 { float:right; width:52%; }
14
  .wl-columns label { display:block; }
15
 
16
  .wl-word-count { clear:both; }
17
- .wl-word-count .wl-check_wordcount_type select { font-size:1.1em; padding:0; }
18
  .wl-word-count label { display:inline; }
19
- .wl-word-count .wl-word_count input { display:inline; width:3em; padding:0; }
20
 
21
- .tw-in-widget-list select { width:100%; }
22
- .wl-options { float:right; width:60%; }
23
  .wl-options .wl-urls { clear:both; }
24
  .wl-options .wl-urls textarea { width:100%; height:7em; font-size:0.96em; line-height:1.25em; }
25
- .wl-tip { font-size:0.9em; line-height:1.25em; }
26
- .wl-visibility input { vertical-align:middle; }
27
- .wl-visibility label { margin-left:1em; padding:0.25em 0.5em; }
28
 
29
- .wl-notes { float:left; width:100%; clear:both; }
30
  .wl-notes textarea { float:left; width:100%; clear:both; height:4em; font-size:1em; line-height:1.25em; }
31
- .wl-visibility label.wl-active { background:#93DB70; }
32
-
33
- li.widget-list-control-item div.widget-control p.wl-visibility { float:left; }
34
- li.widget-list-control-item div.widget-control p.show-support { margin:0; padding:0.5em 0; border-bottom:1px solid #ddd; color:darkgreen; }
35
-
36
- .widget-liquid-right .widget, #wp_inactive_widgets .widget { overflow:visible !important; }
37
-
38
- .widget-context p.show-support { background:#F0E68C; margin:0 0 0.5em 0; padding:0.25em 0.5em; float:left; width:100%; clear:both; }
39
 
 
 
 
1
 
2
+ .widget-context { float:left; width:100%; clear:both; margin:0.5em -12px; padding:0.25em 12px; border-top:1px solid #dfdfdf; border-bottom:1px solid #dfdfdf; background:#eee; }
3
+ .widget .widget-context-inside p { margin:0.5em 0; }
4
+
5
+ .wl-incexc select { max-width:11em; }
 
6
 
 
7
  .wl-columns input { vertical-align:middle; }
8
+ .wl-column-2-1 { float:left; width:48%; }
9
+ .wl-column-2-2 { float:right; width:50%; }
10
  .wl-columns label { display:block; }
11
 
12
  .wl-word-count { clear:both; }
13
+ .wl-word-count .wl-check-wordcount-type select { font-size:1.1em; padding:0; }
14
  .wl-word-count label { display:inline; }
15
+ .wl-word-count .wl-word-count input { display:inline; width:3em; }
16
 
17
+ .wl-options { }
 
18
  .wl-options .wl-urls { clear:both; }
19
  .wl-options .wl-urls textarea { width:100%; height:7em; font-size:0.96em; line-height:1.25em; }
20
+ .wl-visibility { }
 
 
21
 
22
+ .wl-notes { float:left; width:100%; clear:both; margin-bottom:0.5em; }
23
  .wl-notes textarea { float:left; width:100%; clear:both; height:4em; font-size:1em; line-height:1.25em; }
 
 
 
 
 
 
 
 
24
 
25
+ .widget .widget-inside .wl-tip { font-size:0.9em; line-height:1.1; margin:0 0 1em 0; }
readme.txt CHANGED
@@ -1,40 +1,81 @@
1
  === Widget Context ===
2
  Contributors: kasparsd
3
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kaspars%40konstruktors%2ecom&item_name=Widget%20Context%20Plugin%20for%20WordPress&no_shipping=1&no_note=1&tax=0&currency_code=EUR&lc=LV&bn=PP%2dDonationsBF&charset=UTF%2d8
4
  Tags: widget, widget context, context, logic, widget logic, cms
5
- Requires at least: 2.8
6
  Tested up to: 3.5.1
7
- Stable tag: 0.7.2
 
 
 
8
 
9
- Show widgets in context - only on certain posts, front page, category or tag pages etc.
10
 
11
  == Description ==
12
 
13
- Widget Context allows you to specify widget visibility settings.
 
14
 
15
- For news and updates regarding this plugin, check http://konstruktors.com/blog/
 
 
 
 
16
 
17
 
18
  == Installation ==
19
 
20
  * Install the plugin through **Add New Plugin** feature in your WordPress dashboard -- search for Widget Context.
21
- * Widget Context settings will appear automatically under each widget in Design > Widgets.
22
 
23
 
24
  == Changelog ==
25
 
26
- * **0.7.2** - Fix PHP warnings/notices
27
- * **0.7.1** - Confirm that the plugin works with the latest version of WP.
28
- * **0.7** - Bug fix: check for active sidebars only after $paged has been set.
29
- * **0.6** - Don't check for used sidebars on each widget load. Allow absolute URLs in the URL check.
30
- * **0.5** - Added distinction between is_front_page() and is_home(). Remove widgets from wp_get_sidebars_widgets() if they are not being displayed -- this way you can check if a particular sidebar is empty.
31
- * **0.4.5** - Widget output callback couldn't determine the widget_id.
32
- * **0.4.4** - Fixed widget control parameter transfer for widgets that don't use the new widget api.
33
- * **0.4.2** - Initial release on Plugin repository.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
 
36
  == Upgrade Notice ==
37
 
 
 
 
 
 
 
38
  = 0.7.1 =
39
  Confirm that plugin works with the latest version of WordPress.
40
 
@@ -47,4 +88,5 @@ Performance improvements - don't check if sidebar has any widgets on every widge
47
 
48
  == Screenshots ==
49
 
50
- 1. Widget Context settings added at the end of every widget settings
 
1
  === Widget Context ===
2
  Contributors: kasparsd
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kaspars%40konstruktors%2ecom&item_name=Widget%20Context%20Plugin%20for%20WordPress&no_shipping=1&no_note=1&tax=0&currency_code=USD&lc=LV&bn=PP%2dDonationsBF&charset=UTF%2d8
4
  Tags: widget, widget context, context, logic, widget logic, cms
5
+ Requires at least: 3.0
6
  Tested up to: 3.5.1
7
+ Stable tag: 0.8
8
+ License: GPLv2 or later
9
+
10
+ Show or hide widgets on specific posts, pages or sections of your site.
11
 
 
12
 
13
  == Description ==
14
 
15
+ Widget Context allows you to show or hide widgets on certain sections of your site — front page, posts, pages, archives, search, etc. It also features section targeting by URLs (with wildcard support) for maximum flexibility.
16
+
17
 
18
+ = Get Involved: =
19
+
20
+ * News and updates on [konstruktors.com](http://konstruktors.com/blog/),
21
+ * Development and pull requests [on GitHub](https://github.com/kasparsd/widget-context-wporg),
22
+ * Bug reports and suggestions on [WordPress.org forums](http://wordpress.org/support/plugin/widget-context).
23
 
24
 
25
  == Installation ==
26
 
27
  * Install the plugin through **Add New Plugin** feature in your WordPress dashboard -- search for Widget Context.
28
+ * Widget Context settings will appear automatically under each widget under Design > Widgets.
29
 
30
 
31
  == Changelog ==
32
 
33
+ **0.8**
34
+
35
+ * Major code rewrite and refactoring to improve performance and usability.
36
+ * Fix bugs with URL targeting and empty lines in the "Target by URL" textarea.
37
+
38
+ **0.7.2**
39
+
40
+ * Fix PHP warnings/notices. Props to [James Collins](http://om4.com.au/).
41
+
42
+ = 0.7.1 =
43
+
44
+ * Confirm that the plugin works with the latest version of WP.
45
+
46
+ = 0.7 =
47
+
48
+ * Bug fix: check for active sidebars only after $paged has been set.
49
+
50
+ = 0.6 =
51
+
52
+ * Don't check for used sidebars on each widget load. Allow absolute URLs in the URL check.
53
+
54
+ = 0.5 =
55
+
56
+ * Added distinction between is_front_page() and is_home(). Remove widgets from wp_get_sidebars_widgets() if they are not being displayed -- this way you can check if a particular sidebar is empty.
57
+
58
+ = 0.4.5 =
59
+
60
+ * Widget output callback couldn't determine the widget_id.
61
+
62
+ = 0.4.4 =
63
+
64
+ * Fixed widget control parameter transfer for widgets that don't use the new widget api.
65
+
66
+ = 0.4.2 =
67
+
68
+ * Initial release on Plugin repository.
69
 
70
 
71
  == Upgrade Notice ==
72
 
73
+ = 0.8 =
74
+ Major code rewrite and refactoring to improve plugin performance and usability.
75
+
76
+ = 0.7.2 =
77
+ Fix PHP warnings/notices.
78
+
79
  = 0.7.1 =
80
  Confirm that plugin works with the latest version of WordPress.
81
 
88
 
89
  == Screenshots ==
90
 
91
+ 1. Widget Context settings at the bottom of every widget
92
+
screenshot-1.png CHANGED
Binary file
widget-context.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
  /*
3
  Plugin Name: Widget Context
4
- Plugin URI: http://konstruktors.com/
5
  Description: Display widgets in context.
6
- Version: 0.7.2
7
  Author: Kaspars Dambis
8
  Author URI: http://konstruktors.com/
9
 
@@ -33,187 +33,57 @@ class widget_context {
33
  var $options_name = 'widget_logic_options'; // Widget context settings (visibility, etc)
34
  var $context_options = array();
35
  var $words_on_page = 0;
36
- var $did_filter_sidebars = false;
37
 
38
 
39
  function widget_context() {
40
- $this->plugin_path = WP_CONTENT_URL . '/plugins/'. plugin_basename(dirname(__FILE__)) . '/';
41
-
42
  // Amend widget controls with Widget Context controls
43
- add_action('sidebar_admin_setup', array($this, 'attach_widget_context_controls'));
44
- // Enable widget context check only when viewed publicly,
45
- add_action('wp_head', array($this, 'replace_widget_output_callback'));
46
  // Add admin menu for config
47
- add_action('admin_enqueue_scripts', array($this, 'adminCSS'));
48
  // Save widget context settings, when in admin area
49
- add_filter('sidebars_widgets', array($this, 'filter_widgets'), 50);
50
  // Check the number of words on page
51
- add_action('wp_print_scripts', array($this, 'count_words_on_page'), 750);
52
  }
53
-
54
-
55
- function adminCSS() {
56
- wp_enqueue_style('widget-context-admin', $this->plugin_path . 'admin-style.css');
 
 
 
57
  }
58
 
59
-
60
- function filter_widgets($sidebars_widgets) {
61
- global $_wp_sidebars_widgets, $paged;
62
-
63
- if (isset($_POST['wl']) && !empty($_POST['wl']) && is_admin()) {
64
- $this->save_widget_context();
65
- unset($_POST['wl']);
66
-
67
- } elseif (!is_admin() && isset($paged)) {
68
-
69
- // Get widget context options and check visibility settings
70
- if (empty($this->context_options))
71
- $this->context_options = get_option($this->options_name);
72
-
73
- // If we have done this before, return the truth
74
- if ($this->did_filter_sidebars)
75
- return $sidebars_widgets; //return $this->active_sidebars;
76
-
77
- foreach ($sidebars_widgets as $sidebar_id => $widgets) {
78
- // Check if widget will be shown
79
- if ($sidebar_id != 'wp_inactive_widgets' && !empty($widgets)) {
80
- foreach ($widgets as $widget_no => $widget_id) {
81
- if (!$this->check_widget_visibility($this->context_options[$widget_id])) {
82
- unset($sidebars_widgets[$sidebar_id][$widget_no]);
83
- unset($_wp_sidebars_widgets[$sidebar_id][$widget_no]);
84
- }
85
- }
86
- }
87
- }
88
-
89
- $this->did_filter_sidebars = true;
90
- }
91
-
92
- return $sidebars_widgets;
93
- }
94
-
95
-
96
- function save_widget_context() {
97
- global $wp_registered_widgets;
98
-
99
- if (empty($_POST['widget-id']))
100
- $_POST['widget-id'] = array();
101
-
102
- if (isset($_POST['sidebar']) && !empty($_POST['sidebar']))
103
- $sidebar_id = strip_tags((string)$_POST['sidebar']);
104
- else
105
  return;
106
 
107
- // Load widget context settings
108
- $options = get_option($this->options_name);
109
-
110
  // Delete
111
- if (isset($_POST['delete_widget']) && $_POST['delete_widget']) {
112
- $del_id = $_POST['widget-id'];
113
- unset($options[$del_id]);
114
- }
115
-
116
- $new_widget_context_settings = array_values($_POST['wl']);
117
 
118
- // Add/Update
119
- foreach($new_widget_context_settings as $widget_id => $widget_context) {
120
- if (empty($widget_context))
121
- $widget_context = array();
122
- // If neither type of widget logic behaviour is selected, set to default
123
- if (!isset($widget_context['incexc']))
124
- $widget_context['incexc'] = 'notselected';
125
-
126
- $options[(string)$_POST['widget-id']] = $widget_context;
127
- }
128
 
129
- update_option($this->options_name, (array)$options);
130
-
131
- return;
132
- }
133
-
134
-
135
- function attach_widget_context_controls() {
136
- global $wp_registered_widget_controls, $wp_registered_widgets;
137
-
138
- foreach ($wp_registered_widgets as $widget_id => $widget_data) {
139
- // Pass widget id as param, so that we can later call the original callback function
140
- $wp_registered_widget_controls[$widget_id]['params'][]['widget_id'] = $widget_id;
141
- // Store the original callback functions and replace them with Widget Context
142
- $wp_registered_widget_controls[$widget_id]['callback_original_wc'] = $wp_registered_widget_controls[$widget_id]['callback'];
143
- $wp_registered_widget_controls[$widget_id]['callback'] = array($this, 'replace_widget_control_callback');
144
- }
145
- }
146
-
147
-
148
- function replace_widget_output_callback() {
149
- global $wp_registered_widgets;
150
-
151
- // Get widget logic options and check visibility settings
152
- if (empty($this->context_options))
153
- $this->context_options = get_option($this->options_name);
154
-
155
- foreach ($wp_registered_widgets as $widget_id => $widget_data) {
156
- // Check if widget will be shown
157
- $do_show = ( isset($this->context_options[$widget_id]) ) ? $this->check_widget_visibility($this->context_options[$widget_id]) : true;
158
-
159
- if (!$do_show) { // If not shown, remove it temporeraly from the list of existing widgets
160
- unregister_sidebar_widget($widget_id);
161
- } else {
162
- //if (!$wp_registered_widgets[$widget_id]['params'][0]['widget_id']) {
163
- // Save the original widget id
164
- $wp_registered_widgets[$widget_id]['params'][]['widget_id'] = $widget_id;
165
- // Store original widget callbacks
166
- $wp_registered_widgets[$widget_id]['callback_original_wc'] = $wp_registered_widgets[$widget_id]['callback'];
167
- $wp_registered_widgets[$widget_id]['callback'] = array($this, 'replace_widget_output');
168
- }
169
- }
170
  }
171
-
172
-
173
- function replace_widget_output() {
174
- global $wp_registered_widgets;
175
-
176
- $all_params = func_get_args();
177
-
178
- if (is_array($all_params[2]))
179
- $widget_id = $all_params[2]['widget_id'];
180
- else
181
- $widget_id = $all_params[1]['widget_id'];
182
-
183
- $widget_callback = $wp_registered_widgets[$widget_id]['callback_original_wc'];
184
-
185
- if (is_callable($widget_callback)) {
186
- call_user_func_array($widget_callback, $all_params);
187
- return true;
188
- } elseif (!is_callable($widget_callback)) {
189
- // print_r($all_params);
190
- print '<!-- widget context: could not call the original callback function -->';
191
- return false;
192
- } else {
193
  return false;
194
- }
195
- }
196
-
197
-
198
- function replace_widget_control_callback() {
199
- global $wp_registered_widget_controls;
200
-
201
- $all_params = func_get_args();
202
- if (is_array($all_params[1]))
203
- $widget_id = $all_params[1]['widget_id'];
204
- else
205
- $widget_id = $all_params[0]['widget_id'];
206
-
207
- $original_callback = $wp_registered_widget_controls[$widget_id]['callback_original_wc'];
208
-
209
- // Display the original callback
210
- if (isset($original_callback) && is_callable($original_callback)) {
211
- call_user_func_array($original_callback, $all_params);
212
- } else {
213
- print '<!-- widget context [controls]: could not call the original callback function -->';
214
- }
215
-
216
- print $this->display_widget_context($original_callback, $widget_id);
217
  }
218
 
219
 
@@ -223,73 +93,54 @@ class widget_context {
223
  else
224
  $uri = $_SERVER['REQUEST_URI'];
225
 
226
- $url = (!empty($_SERVER['HTTPS']))
227
  ? "https://".$_SERVER['SERVER_NAME'].$uri
228
  : "http://".$_SERVER['SERVER_NAME'].$uri;
229
-
230
- if (substr($url, -1) == '/')
231
- $url = substr($url, 0, -1);
232
-
233
- return $url;
234
  }
 
235
 
236
  // Thanks to Drupal: http://api.drupal.org/api/function/drupal_match_path/6
237
- function match_path($path, $patterns) {
238
- static $regexps;
239
-
240
- // get home url;
241
- $home_url = get_bloginfo('url');
242
-
243
- // add trailing slash if missing
244
- if (substr($home_url, -1) !== '/')
245
- $home_url = $home_url . '/';
246
-
247
- // Check if user has specified the absolute url
248
- // else strip home url and check only REQUEST_URI part
249
- if ($path !== $home_url && !strstr($patterns, $_SERVER['SERVER_NAME']))
250
- $path = str_replace($home_url, '', $path);
251
-
252
- // Remove http:// from the url user has specified
253
- if (strstr($patterns, 'http://'))
254
- $patterns = str_replace('http://', '', $patterns);
255
-
256
- // Remove http:// from the current url
257
- if (strstr($path, 'http://'))
258
- $path = str_replace('http://', '', $path);
259
-
260
- if (!isset($regexps[$patterns])) {
261
- $regexps[$patterns] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<home\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote($home_url, '/') .'\2'), preg_quote($patterns, '/')) .')$/';
262
- }
263
- return preg_match($regexps[$patterns], $path);
264
  }
265
 
266
 
267
  function count_words_on_page() {
268
  global $wp_query;
269
 
270
- $this->words_on_page = 0;
271
-
272
- if (count($wp_query->posts) > 0 && function_exists('strip_shortcodes')) {
273
- foreach ($wp_query->posts as $pid => $post_data) {
274
- if ($post_data->post_status == 'publish') {
275
- $pure_content = strip_shortcodes($post_data->post_content);
276
- if (!is_single() && !is_page()) {
277
- if (preg_match('/<!--more(.*?)?-->/', $pure_content, $matches)) {
278
- $pure_content = explode($matches[0], $pure_content, 2);
279
- $this->words_on_page += str_word_count(strip_tags($pure_content[0]));
280
- }
281
- } else {
282
- $this->words_on_page += str_word_count(strip_tags($pure_content));
283
- }
284
- }
285
- }
286
- }
287
  }
 
288
 
289
- function check_widget_visibility($vis_settings = array()) {
290
- global $paged;
 
 
291
 
292
- if (empty($vis_settings))
 
 
 
 
 
293
  return true;
294
 
295
  $do_show = true;
@@ -298,88 +149,54 @@ class widget_context {
298
  $do_show_by_word_count = false;
299
 
300
  // Check by current URL
301
- if (!empty($vis_settings['url']['urls'])) {
302
- // Split on line breaks
303
- $split_urls = split("[\n ]+", (string)$vis_settings['url']['urls']);
304
- $current_url = $this->get_current_url();
305
- $ignore_url = false;
306
- foreach ($split_urls as $id => $check_url) {
307
- $check_url = trim($check_url);
308
- if ($check_url !== '') {
309
- if ($this->match_path($current_url, $check_url))
310
- $do_show_by_url = true;
311
- } else {
312
- $ignore_url = true;
313
- }
314
- }
315
-
316
- if (!$ignore_url && $do_show_by_url)
317
  $do_show_by_url = true;
318
- else
319
- $do_show_by_url = false;
320
- }
321
 
322
  // Check by tag settings
323
- if (!empty($vis_settings['location'])) {
324
  $currently = array();
325
 
326
- if (is_front_page() && $paged < 2) $currently['is_front_page'] = true;
327
- if (is_home() && $paged < 2) $currently['is_home'] = true;
328
- if (is_page() && !is_attachment()) $currently['is_page'] = true;
329
- if (is_single() && !is_attachment()) $currently['is_single'] = true;
330
- if (is_archive()) $currently['is_archive'] = true;
331
- if (is_category()) $currently['is_category'] = true;
332
- if (is_tag()) $currently['is_tag'] = true;
333
- if (is_author()) $currently['is_author'] = true;
334
- if (is_search()) $currently['is_search'] = true;
335
- if (is_404()) $currently['is_404'] = true;
336
- if (is_attachment()) $currently['is_attachment'] = true;
337
 
338
  // Check for selected pages/sections
339
- $current_location = array_keys($currently);
340
- $visibility_options = array_keys($vis_settings['location']);
341
- foreach($current_location as $location_id) {
342
- if (in_array($location_id, $visibility_options))
343
- $do_show_by_select = true;
344
- }
345
-
346
- // Check for word count
347
- $word_count_to_check = (int)$vis_settings['location']['word_count'];
348
 
349
- $ignore_word_count = false;
350
- if (isset($vis_settings['location']['check_wordcount']) && $vis_settings['location']['check_wordcount'] == 'on' && $word_count_to_check > 1) {
 
 
351
  $check_type = $vis_settings['location']['check_wordcount_type'];
352
-
353
- if (($check_type == 'more') && ($this->words_on_page > $word_count_to_check)) {
354
- print '<!-- showing because '. $this->words_on_page .' > '. $word_count_to_check .' -->';
355
- $do_show_by_word_count = true;
356
- } elseif (($check_type == 'less') && ($this->words_on_page < $word_count_to_check)) {
357
- print '<!-- showing because '. $this->words_on_page .' < '. $word_count_to_check .' -->';
358
  $do_show_by_word_count = true;
359
- }
360
- } else {
361
- $ignore_word_count = true;
362
- }
363
-
364
- if (!$ignore_word_count && $do_show_by_word_count)
365
- $do_show_by_word_count = true;
366
- else
367
- $do_show_by_word_count = false;
368
-
369
  }
370
 
371
  // Combine all context checks
372
  if ($do_show_by_word_count || $do_show_by_url || $do_show_by_select)
373
  $one_is_true = true;
374
  elseif (!$do_show_by_word_count || !$do_show_by_url || !$do_show_by_select)
375
- $one_is_true = false;
376
-
377
 
378
  if (($vis_settings['incexc'] == 'selected') && $one_is_true) {
379
- // Show on selected
380
  $do_show = true;
381
  } elseif (($vis_settings['incexc'] == 'notselected') && !$one_is_true) {
382
- // Hide on selected
383
  $do_show = true;
384
  } elseif (!empty($vis_settings['incexc'])) {
385
  $do_show = false;
@@ -387,209 +204,165 @@ class widget_context {
387
  $do_show = true;
388
  }
389
 
390
- // Hide if selected
391
- if ($vis_settings['incexc'] == 'hide') {
392
- $do_show = false;
393
- }
394
-
395
  return $do_show;
396
  }
397
-
398
-
399
- function display_widget_context($args = array(), $wid = null) {
400
-
401
- $group = 'location'; // Produces: wl[$wid][$group][homepage/singlepost/...]
402
- $options = get_option($this->options_name);
403
-
404
- $out = '<div class="widget-context"><div class="widget-context-inside">';
405
- $out .= '<div class="wl-header"><h5>Widget Context:</h5>'
406
- . '<p class="wl-visibility">'
407
- . $this->make_simple_radio($options, $wid, 'incexc', 'selected', '<strong>Show</strong> on selected')
408
- . $this->make_simple_radio($options, $wid, 'incexc', 'notselected', '<strong>Hide</strong> on selected')
409
- . $this->make_simple_radio($options, $wid, 'incexc', 'hide', 'Hide')
 
 
 
 
 
 
 
 
 
 
 
410
  . '</p></div>'
411
 
412
- . $this->show_support() // you can comment out this line, if you want.
413
-
414
- . '<div class="wl-wrap-columns">'
415
-
416
- . '<div class="wl-columns">'
417
- . '<div class="wl-column-2-1"><p>'
418
- . $this->make_simple_checkbox($options, $wid, $group, 'is_front_page', __('Front Page'))
419
- . $this->make_simple_checkbox($options, $wid, $group, 'is_home', __('Blog Index'))
420
- . $this->make_simple_checkbox($options, $wid, $group, 'is_single', __('Single Post'))
421
- . $this->make_simple_checkbox($options, $wid, $group, 'is_page', __('Single Page'))
422
- . $this->make_simple_checkbox($options, $wid, $group, 'is_attachment', __('Attachment'))
423
- . $this->make_simple_checkbox($options, $wid, $group, 'is_search', __('Search'))
424
- . '</p></div>'
425
- . '<div class="wl-column-2-2"><p>'
426
- . $this->make_simple_checkbox($options, $wid, $group, 'is_archive', __('All Archives'))
427
- . $this->make_simple_checkbox($options, $wid, $group, 'is_category', __('Category Archive'))
428
- . $this->make_simple_checkbox($options, $wid, $group, 'is_tag', __('Tag Archive'))
429
- . $this->make_simple_checkbox($options, $wid, $group, 'is_author', __('Author Archive'))
430
- . $this->make_simple_checkbox($options, $wid, $group, 'is_404', __('404 Error'))
431
- . '</p></div>'
432
-
433
- . '<div class="wl-word-count"><p>'
434
- . $this->make_simple_checkbox($options, $wid, $group, 'check_wordcount', __('Has'))
435
- . $this->make_simple_dropdown($options, $wid, $group, 'check_wordcount_type', array('less' => __('less'), 'more' => __('more')), '', __('than'))
436
- . $this->make_simple_textfield($options, $wid, $group, 'word_count', null, __('words'))
437
- . '</p></div>'
438
-
439
- . '</div>'
440
-
441
- . '<div class="wl-options">'
442
- . $this->make_simple_textarea($options, $wid, 'url', 'urls', __('or target by URL'), __('Enter one location fragment per line. Use <strong>*</strong> character as a wildcard. Use <strong><code>&lt;home&gt;</code></strong> to select front page. Examples: <strong><code>category/peace/*</code></strong> to target all <em>peace</em> category posts; <strong><code>2012/*</code></strong> to target articles written in year 2012.'))
443
- . '</div>'
444
 
 
 
445
  . '</div>'
446
 
447
- . $this->make_simple_textarea($options, $wid, 'general', 'notes', __('Notes (invisible to public)'))
448
  . '</div></div>';
449
-
450
- return $out;
451
- }
452
-
453
- function printAdminOptions() {
454
- global $wp_registered_widget_controls, $wp_registered_widgets;
455
-
456
- print '<div class="wrap"><h2>'.__('Widget Context Plugin Settings') . '</h2></div>';
457
- print '<pre>'; print_r(get_option($this->options_name)); print '</pre>';
458
  }
459
 
460
 
461
-
462
  /*
463
 
464
  Interface constructors
465
 
466
  */
 
467
 
468
- function show_support() {
469
- $out = '';
470
- if (rand(1,3) == 1)
471
- $out = '<p class="show-support"><small>If you find <em>Widget Context</em> plugin useful, please <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kaspars%40konstruktors%2ecom&item_name=Widget%20Context%20Plugin%20for%20WordPress&no_shipping=1&no_note=1&tax=0&currency_code=EUR&lc=LV&bn=PP%2dDonationsBF&charset=UTF%2d8">donate</a> a few silver coins to support the development. Thanks. <a href="http://konstruktors.com/blog/">Kaspars</a></small></p>';
472
-
473
- return $out;
 
 
474
  }
 
475
 
476
- function makeSubmitButton() {
477
- return '<p class="submit"><input type="submit" name="Submit" value="' . __('Save Options') . '" /></p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478
  }
479
-
480
- function make_simple_checkbox($options, $prefix, $id, $fieldname = null, $label) {
481
- if ($fieldname !== null) {
482
- $value = strip_tags($options[$prefix][$id][$fieldname]);
483
- $fieldname = '[' . $fieldname . ']';
484
- } else {
485
- $value = strip_tags($options[$prefix][$id]);
486
- $fieldname = '';
487
- }
488
-
489
- $prefix = '[' . $prefix . ']';
490
- $id = '[' . $id . ']';
491
-
492
- if (!empty($value)) {
493
- $value = 1; $checked = 'checked="checked"'; $classname = 'wl-active';
494
- } else {
495
- $value = 0; $checked = ''; $classname = 'wl-inactive';
496
- }
497
-
498
- $out = '<label class="' . $classname . '"><input type="checkbox" name="wl'. $prefix . $id . $fieldname . '" '. $checked .' />&nbsp;'
499
- . $label . '</label> ';
500
-
501
- return $out;
502
  }
503
-
504
- function make_simple_textarea($options, $prefix, $id, $fieldname = null, $label, $tip = null) {
505
- $classname = $fieldname;
506
-
507
- if ($fieldname !== null) {
508
- $value = $options[$prefix][$id][$fieldname];
509
- $fieldname = '[' . $fieldname . ']';
510
- } else {
511
- $value = $options[$prefix][$id];
512
- $fieldname = '';
513
- }
514
- $prefix = '[' . $prefix . ']';
515
- $id = '[' . $id . ']';
516
-
517
- if ($tip !== null) $tip = '<p class="wl-tip">' . $tip . '</p>';
518
-
519
- $out = '<div class="wl-'. $classname .'">'
520
- . '<label for="wl'. $prefix . $id . $fieldname . '"><strong>' . $label . '</strong></label>'
521
- . '<textarea name="wl'. $prefix . $id . $fieldname . '" id="wl'. $prefix . $id . $fieldname . '">'. stripslashes($value) .'</textarea>'
522
- . $tip . '</div>';
523
- return $out;
 
 
 
 
 
524
  }
525
 
526
- function make_simple_textfield($options, $prefix, $id, $fieldname = null, $label_before = null, $label_after = null) {
527
- $classname = $fieldname;
528
-
529
- if ($fieldname !== null) {
530
- $value = $options[$prefix][$id][$fieldname];
531
- $fieldname = '[' . $fieldname . ']';
532
- } else {
533
- $value = $options[$prefix][$id];
534
- $fieldname = '';
535
- }
536
- $prefix = '[' . $prefix . ']';
537
- $id = '[' . $id . ']';
538
-
539
- return '<label class="wl-'. $classname . '">' . $label_before . ' '
540
- . '<input type="text" name="wl'. $prefix . $id . $fieldname . '" value="'. $value .'" /> '
541
- . $label_after . '</label>';
542
- }
543
-
544
- function make_simple_radio($options, $id, $fieldname, $value, $label = null) {
545
- if ($options[$id][$fieldname] == $value) {
546
- $checked = 'checked="checked"'; $classname = 'wl-active';
547
- } else {
548
- $checked = ''; $classname = 'wl-inactive';
549
- }
550
-
551
- $id = '[' . $id . ']';
552
- $fieldname = '[' . $fieldname . ']';
553
-
554
- $out = '<label class="' . $classname . ' label-'. $value .'"><input type="radio" name="wl'. $id . $fieldname . '" value="'. $value .'" '. $checked .' /> '
555
- . $label . '</label>';
556
-
557
- return $out;
558
  }
559
 
560
- function make_simple_dropdown($options, $prefix, $id, $fieldname = null, $selection = array(), $label_before = null, $label_after = null) {
561
- $classname = $fieldname;
562
-
563
- if ($fieldname !== null) {
564
- $value = $options[$prefix][$id][$fieldname];
565
- $fieldname = '[' . $fieldname . ']';
566
- } else {
567
- $value = $options[$prefix][$id];
568
- $fieldname = '';
569
- }
570
- $prefix = '[' . $prefix . ']';
571
- $id = '[' . $id . ']';
572
-
573
- $list = '<label class="wl-'. $classname .'"><select name="wl'. $prefix . $id . $fieldname . '">'
574
- . $label_before . ' ';
575
-
576
- if (!empty($selection)) {
577
- foreach ($selection as $sid => $svalue) {
578
- if ($value == $sid) {
579
- $selected = 'selected="selected"';
580
- } else {
581
- $selected = '';
582
- }
583
-
584
- $list .= '<option value="' . $sid . '" ' . $selected . '>' . $svalue . '</option>';
585
- }
586
- } else {
587
- $list .= '<option value="error" selected="selected">'. __('No options given') .'</option>';
588
- }
589
-
590
- $list .= '</select> ' . $label_after . '</label>';
591
-
592
- return $list;
593
  }
 
 
594
  }
595
 
1
  <?php
2
  /*
3
  Plugin Name: Widget Context
4
+ Plugin URI: http://wordpress.org/extend/plugins/widget-context/
5
  Description: Display widgets in context.
6
+ Version: 0.8
7
  Author: Kaspars Dambis
8
  Author URI: http://konstruktors.com/
9
 
33
  var $options_name = 'widget_logic_options'; // Widget context settings (visibility, etc)
34
  var $context_options = array();
35
  var $words_on_page = 0;
 
36
 
37
 
38
  function widget_context() {
39
+ // Load plugin settings
40
+ add_action( 'init', array( $this, 'load_plugin_settings' ) );
41
  // Amend widget controls with Widget Context controls
42
+ add_action( 'in_widget_form', array( $this, 'display_widget_context' ), 10, 3 );
43
+ // Hide the widget if necessary
44
+ add_filter( 'widget_display_callback', array( $this, 'maybe_hide_widget' ), 10, 3 );
45
  // Add admin menu for config
46
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
47
  // Save widget context settings, when in admin area
48
+ add_filter( 'admin_init', array( $this, 'save_widget_context_settings' ) );
49
  // Check the number of words on page
50
+ add_action( 'wp', array( $this, 'count_words_on_page' ) );
51
  }
52
+
53
+
54
+ function load_plugin_settings() {
55
+ $this->context_options = get_option( $this->options_name );
56
+
57
+ if ( ! is_array( $this->context_options ) || empty( $this->context_options ) )
58
+ $this->context_options = array();
59
  }
60
 
61
+
62
+ function admin_scripts() {
63
+ wp_enqueue_style( 'widget-context-admin', WP_CONTENT_URL . '/plugins/'. basename(__DIR__) . '/admin-style.css' );
64
+ }
65
+
66
+
67
+ function save_widget_context_settings() {
68
+ if ( ! current_user_can( 'edit_theme_options' ) || empty( $_POST ) || ! isset( $_POST['sidebar'] ) || empty( $_POST['sidebar'] ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  return;
70
 
 
 
 
71
  // Delete
72
+ if ( isset( $_POST['delete_widget'] ) && $_POST['delete_widget'] )
73
+ unset( $this->context_options[ $_POST['widget-id'] ] );
 
 
 
 
74
 
75
+ // Add / Update
76
+ $this->context_options = array_merge( $this->context_options, $_POST['wl'] );
 
 
 
 
 
 
 
 
77
 
78
+ update_option( $this->options_name, $this->context_options );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
+
81
+
82
+ function maybe_hide_widget( $instance, $widget_object, $args ) {
83
+ if ( ! $this->check_widget_visibility( $args['widget_id'] ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  return false;
85
+
86
+ return $instance;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  }
88
 
89
 
93
  else
94
  $uri = $_SERVER['REQUEST_URI'];
95
 
96
+ return (!empty($_SERVER['HTTPS']))
97
  ? "https://".$_SERVER['SERVER_NAME'].$uri
98
  : "http://".$_SERVER['SERVER_NAME'].$uri;
 
 
 
 
 
99
  }
100
+
101
 
102
  // Thanks to Drupal: http://api.drupal.org/api/function/drupal_match_path/6
103
+ function match_path( $path, $patterns ) {
104
+ $patterns_safe = array();
105
+
106
+ // Strip home url and check only the REQUEST_URI part
107
+ $path = trim( str_replace( trailingslashit( get_bloginfo('url') ), '', $path ), '/' );
108
+
109
+ foreach ( explode( "\n", $patterns ) as $pattern )
110
+ $patterns_safe[] = trim( trim( $pattern ), '/' );
111
+
112
+ $regexps = '/^('. preg_replace( array( '/(\r\n|\n| )+/', '/\\\\\*/' ), array( '|', '.*' ), preg_quote( implode( "\n", array_filter( $patterns_safe, 'trim' ) ), '/' ) ) .')$/';
113
+
114
+ // Debug
115
+ //echo $regexps;
116
+ //print_r(array_filter( $patterns_safe, 'trim' ));
117
+
118
+ return preg_match( $regexps, $path );
 
 
 
 
 
 
 
 
 
 
 
119
  }
120
 
121
 
122
  function count_words_on_page() {
123
  global $wp_query;
124
 
125
+ if ( empty( $wp_query->posts ) || is_admin() )
126
+ return;
127
+
128
+ foreach ( $wp_query->posts as $post_data )
129
+ $this->words_on_page += str_word_count( strip_tags( strip_shortcodes( $post_data->post_content ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
131
+
132
 
133
+ function check_widget_visibility( $widget_id ) {
134
+ // Show widget because no context settings found
135
+ if ( ! isset( $this->context_options[ $widget_id ] ) )
136
+ return true;
137
 
138
+ $vis_settings = $this->context_options[ $widget_id ];
139
+
140
+ // Hide/show if forced
141
+ if ( $vis_settings['incexc'] == 'hide' )
142
+ return false;
143
+ elseif ( $vis_settings['incexc'] == 'show' )
144
  return true;
145
 
146
  $do_show = true;
149
  $do_show_by_word_count = false;
150
 
151
  // Check by current URL
152
+ if ( ! empty( $vis_settings['url']['urls'] ) )
153
+ if ( $this->match_path( $this->get_current_url(), $vis_settings['url']['urls'] ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  $do_show_by_url = true;
 
 
 
155
 
156
  // Check by tag settings
157
+ if ( ! empty( $vis_settings['location'] ) ) {
158
  $currently = array();
159
 
160
+ if ( is_front_page() && ! is_paged() ) $currently['is_front_page'] = true;
161
+ if ( is_home() && ! is_paged() ) $currently['is_home'] = true;
162
+ if ( is_page() && ! is_attachment() ) $currently['is_page'] = true;
163
+ if ( is_single() && ! is_attachment() ) $currently['is_single'] = true;
164
+ if ( is_archive() ) $currently['is_archive'] = true;
165
+ if ( is_category() ) $currently['is_category'] = true;
166
+ if ( is_tag() ) $currently['is_tag'] = true;
167
+ if ( is_author() ) $currently['is_author'] = true;
168
+ if ( is_search() ) $currently['is_search'] = true;
169
+ if ( is_404() ) $currently['is_404'] = true;
170
+ if ( is_attachment() ) $currently['is_attachment'] = true;
171
 
172
  // Check for selected pages/sections
173
+ if ( array_intersect_key( $currently, $vis_settings['location'] ) )
174
+ $do_show_by_select = true;
 
 
 
 
 
 
 
175
 
176
+ // Word count
177
+ if ( isset( $vis_settings['location']['check_wordcount'] ) ) {
178
+ // Check for word count
179
+ $word_count_to_check = intval( $vis_settings['location']['word_count'] );
180
  $check_type = $vis_settings['location']['check_wordcount_type'];
181
+
182
+ if ( $this->words_on_page > $word_count_to_check && $check_type == 'more' )
 
 
 
 
183
  $do_show_by_word_count = true;
184
+ else
185
+ $do_show_by_word_count = false;
186
+ }
 
 
 
 
 
 
 
187
  }
188
 
189
  // Combine all context checks
190
  if ($do_show_by_word_count || $do_show_by_url || $do_show_by_select)
191
  $one_is_true = true;
192
  elseif (!$do_show_by_word_count || !$do_show_by_url || !$do_show_by_select)
193
+ $one_is_true = false;
 
194
 
195
  if (($vis_settings['incexc'] == 'selected') && $one_is_true) {
196
+ // Show on selected
197
  $do_show = true;
198
  } elseif (($vis_settings['incexc'] == 'notselected') && !$one_is_true) {
199
+ // Hide on selected
200
  $do_show = true;
201
  } elseif (!empty($vis_settings['incexc'])) {
202
  $do_show = false;
204
  $do_show = true;
205
  }
206
 
 
 
 
 
 
207
  return $do_show;
208
  }
209
+
210
+
211
+ function display_widget_context( $form, $return, $instance ) {
212
+
213
+ echo '<div class="widget-context"><div class="widget-context-inside">'
214
+ . '<p class="wl-visibility">'
215
+ . $this->make_simple_dropdown( array( $form->id, 'incexc' ), array( 'show' => __('Show everywhere'), 'selected' => __('Show on selected'), 'notselected' => __('Hide on selected'), 'hide' => __('Hide everywhere') ), sprintf( '<strong>%s</strong>', __( 'Widget Context' ) ) )
216
+ . '</p>'
217
+
218
+ . '<div class="wl-columns">'
219
+ . '<div class="wl-column-2-1"><p>'
220
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_front_page' ), __('Front Page') )
221
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_home' ), __('Blog Index') )
222
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_single' ), __('All Posts') )
223
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_page' ), __('All Pages') )
224
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_attachment' ), __('All Attachments') )
225
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_search' ), __('Search') )
226
+ . '</p></div>'
227
+ . '<div class="wl-column-2-2"><p>'
228
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_archive' ), __('All Archives') )
229
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_category' ), __('Category Archive') )
230
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_tag' ), __('Tag Archive') )
231
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_author' ), __('Author Archive') )
232
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'is_404' ), __('404 Error') )
233
  . '</p></div>'
234
 
235
+ . '<div class="wl-word-count"><p>'
236
+ . $this->make_simple_checkbox( array( $form->id, 'location', 'check_wordcount' ), __('Has') )
237
+ . $this->make_simple_dropdown( array( $form->id, 'location', 'check_wordcount_type' ), array('less' => __('less'), 'more' => __('more')), '', __('than') )
238
+ . $this->make_simple_textfield( array( $form->id, 'location', 'word_count' ), __('words') )
239
+ . '</p></div>'
240
+ . '</div>'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
 
242
+ . '<div class="wl-options">'
243
+ . $this->make_simple_textarea( array( $form->id, 'url', 'urls' ), __('or target by URL'), __('Enter one location fragment per line. Use <code>*</code> character as a wildcard. Don\'t include the domain name.'))
244
  . '</div>'
245
 
246
+ . $this->make_simple_textarea( array( $form->id, 'general', 'notes' ), __('Notes (invisible to public)'))
247
  . '</div></div>';
248
+
 
 
 
 
 
 
 
 
249
  }
250
 
251
 
 
252
  /*
253
 
254
  Interface constructors
255
 
256
  */
257
+
258
 
259
+ function make_simple_checkbox( $name, $label ) {
260
+ return sprintf(
261
+ '<label class="wl-%s"><input type="checkbox" value="1" name="wl%s" %s />&nbsp;%s</label>',
262
+ $this->get_field_classname( $name ),
263
+ $this->get_field_name( $name ),
264
+ checked( (bool) $this->get_field_value( $name ), 1, false ),
265
+ $label
266
+ );
267
  }
268
+
269
 
270
+ function make_simple_textarea( $name, $label, $tip = null ) {
271
+ if ( $tip )
272
+ $tip = sprintf( '<p class="wl-tip">%s</p>', $tip );
273
+
274
+ return sprintf(
275
+ '<div class="wl-%s">
276
+ <label>
277
+ <strong>%s</strong>
278
+ <textarea name="wl%s">%s</textarea>
279
+ </label>
280
+ %s
281
+ </div>',
282
+ $this->get_field_classname( $name ),
283
+ $label,
284
+ $this->get_field_name( $name ),
285
+ esc_textarea( $this->get_field_value( $name ) ),
286
+ $tip
287
+ );
288
  }
289
+
290
+
291
+ function make_simple_textfield( $name, $label_before = null, $label_after = null) {
292
+ return sprintf(
293
+ '<label class="wl-%s">%s <input type="text" name="wl%s" value="%s" /> %s</label>',
294
+ $this->get_field_classname( $name ),
295
+ $label_before,
296
+ $this->get_field_name( $name ),
297
+ esc_attr( $this->get_field_value( $name ) ),
298
+ $label_after
299
+ );
 
 
 
 
 
 
 
 
 
 
 
 
300
  }
301
+
302
+
303
+ function make_simple_dropdown( $name, $selection = array(), $label_before = null, $label_after = null ) {
304
+ $value = esc_attr( $this->get_field_value( $name ) );
305
+ $options = array();
306
+
307
+ if ( empty( $selection ) )
308
+ $options[] = sprintf( '<option value="">%s</option>', __('No options given') );
309
+
310
+ foreach ( $selection as $sid => $svalue )
311
+ $options[] = sprintf( '<option value="%s" %s>%s</option>', $sid, selected( $value, $sid, false ), $svalue );
312
+
313
+ return sprintf(
314
+ '<label class="wl-%s">
315
+ %s
316
+ <select name="wl%s">
317
+ %s
318
+ </select>
319
+ %s
320
+ </label>',
321
+ $this->get_field_classname( $name ),
322
+ $label_before,
323
+ $this->get_field_name( $name ),
324
+ implode( '', $options ),
325
+ $label_after
326
+ );
327
  }
328
 
329
+ /**
330
+ * Returns [part1][part2][partN] from array( 'part1', 'part2', 'part3' )
331
+ * @param array $parts i.e. array( 'part1', 'part2', 'part3' )
332
+ * @return string i.e. [part1][part2][partN]
333
+ */
334
+ function get_field_name( $parts ) {
335
+ return esc_attr( sprintf( '[%s]', implode( '][', $parts ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  }
337
 
338
+ function get_field_classname( $parts ) {
339
+ return sanitize_html_class( str_replace( '_', '-', end( $parts ) ) );
340
+ }
341
+
342
+
343
+ /**
344
+ * Given option keys return its value
345
+ * @param array $parts i.e. array( 'part1', 'part2', 'part3' )
346
+ * @param array $options i.e. array( 'part1' => array( 'part2' => array( 'part3' => 'VALUE' ) ) )
347
+ * @return string Returns option value
348
+ */
349
+ function get_field_value( $parts, $options = array() ) {
350
+ if ( empty( $options ) )
351
+ $options = $this->context_options;
352
+
353
+ if ( ! empty( $parts ) )
354
+ $part = array_shift( $parts );
355
+
356
+ if ( isset( $part ) && isset( $options[ $part ] ) && is_array( $options[ $part ] ) )
357
+ $value = $this->get_field_value( $parts, $options[ $part ] );
358
+ elseif ( isset( $options[ $part ] ) )
359
+ $value = $options[ $part ];
360
+ else
361
+ $value = '';
362
+
363
+ return trim( $value );
 
 
 
 
 
 
 
364
  }
365
+
366
+
367
  }
368