PluginProbe
Widget Context / 0.6
Widget Context v0.6
1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 trunk 0.4.1 0.4.2 0.4.3 0.4.4 0.4.5 0.6 0.7 0.7.1 0.7.2 0.8 0.8.1 All 30 releases
widget-context / widget-context.php

widget-context.php in Widget Context 0.6, at widget-context.php

591 lines 20.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Widget Context
4 Plugin URI: http://konstruktors.com/blog/
5 Description: Display widgets in context.
6 Version: 0.6
7 Author: Kaspars Dambis
8 Author URI: http://konstruktors.com/blog/
9
10 For changelog see readme.txt
11 ----------------------------
12
13 Copyright 2009 Kaspars Dambis (email: kaspars@konstruktors.com)
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28 // Go!
29 new widget_context();
30
31
32 class widget_context {
33
34 var $options_name = 'widget_logic_options'; // Widget context settings (visibility, etc)
35 var $context_options = array();
36 var $words_on_page = 0;
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_menu', array($this, 'addAdminOptions'));
48 add_action('admin_enqueue_scripts', array($this, 'adminCSS'));
49 // Save widget context settings, when in admin area
50 add_filter('sidebars_widgets', array($this, 'filter_widgets'));
51 // Check the number of words on page
52 add_action('wp_print_scripts', array($this, 'count_words_on_page'), 750);
53 }
54
55
56 function addAdminOptions() {
57 // add_options_page('Widget Context', 'Widget Context', 10, basename(__FILE__), array($this, 'printAdminOptions'));
58 }
59
60
61 function adminCSS() {
62 wp_enqueue_style('widget-context-admin', $this->plugin_path . 'admin-style.css');
63 }
64
65
66 function filter_widgets($sidebars_widgets) {
67 if (isset($_POST['wl']) && !empty($_POST['wl']) && is_admin()) {
68 $this->save_widget_context();
69 unset($_POST['wl']);
70
71 } elseif (!is_admin() && empty($this->context_options)) {
72 // This way we can check if a particular sidebar is empty
73 if (empty($this->context_options)) // Get widget context options and check visibility settings
74 $this->context_options = get_option($this->options_name);
75
76 foreach ($sidebars_widgets as $sidebar_id => $widgets) {
77 // Check if widget will be shown
78 if ($sidebar_id != 'wp_inactive_widgets' && !empty($widgets)) {
79 foreach ($widgets as $widget_no => $widget_id) {
80 if (!$this->check_widget_visibility($this->context_options[$widget_id]))
81 unset($sidebars_widgets[$sidebar_id][$widget_no]);
82 }
83 }
84 }
85 }
86
87 return $sidebars_widgets;
88 }
89
90
91 function save_widget_context() {
92 global $wp_registered_widgets;
93
94 if (empty($_POST['widget-id']))
95 $_POST['widget-id'] = array();
96
97 if (isset($_POST['sidebar']) && !empty($_POST['sidebar']))
98 $sidebar_id = strip_tags((string)$_POST['sidebar']);
99 else
100 return;
101
102 // Load widget context settings
103 $options = get_option($this->options_name);
104
105 // Delete
106 if (isset($_POST['delete_widget']) && $_POST['delete_widget']) {
107 $del_id = $_POST['widget-id'];
108 unset($options[$del_id]);
109 }
110
111 $new_widget_context_settings = array_values($_POST['wl']);
112
113 // Add/Update
114 foreach($new_widget_context_settings as $widget_id => $widget_context) {
115 if (empty($widget_context))
116 $widget_context = array();
117 // If neither type of widget logic behaviour is selected, set to default
118 if (!isset($widget_context['incexc']))
119 $widget_context['incexc'] = 'notselected';
120
121 $options[(string)$_POST['widget-id']] = $widget_context;
122 }
123
124 update_option($this->options_name, (array)$options);
125
126 return;
127 }
128
129
130 function attach_widget_context_controls() {
131 global $wp_registered_widget_controls, $wp_registered_widgets;
132
133 foreach ($wp_registered_widgets as $widget_id => $widget_data) {
134 // Pass widget id as param, so that we can later call the original callback function
135 $wp_registered_widget_controls[$widget_id]['params'][]['widget_id'] = $widget_id;
136 // Store the original callback functions and replace them with Widget Context
137 $wp_registered_widget_controls[$widget_id]['callback_original_wc'] = $wp_registered_widget_controls[$widget_id]['callback'];
138 $wp_registered_widget_controls[$widget_id]['callback'] = array($this, 'replace_widget_control_callback');
139 }
140 }
141
142
143 function replace_widget_output_callback() {
144 global $wp_registered_widgets;
145
146 // Get widget logic options and check visibility settings
147 if (empty($this->context_options))
148 $this->context_options = get_option($this->options_name);
149
150 foreach ($wp_registered_widgets as $widget_id => $widget_data) {
151 // Check if widget will be shown
152 $do_show = $this->check_widget_visibility($this->context_options[$widget_id]);
153
154 if (!$do_show) { // If not shown, remove it temporeraly from the list of existing widgets
155 unregister_sidebar_widget($widget_id);
156 } else {
157 //if (!$wp_registered_widgets[$widget_id]['params'][0]['widget_id']) {
158 // Save the original widget id
159 $wp_registered_widgets[$widget_id]['params'][]['widget_id'] = $widget_id;
160 // Store original widget callbacks
161 $wp_registered_widgets[$widget_id]['callback_original_wc'] = $wp_registered_widgets[$widget_id]['callback'];
162 $wp_registered_widgets[$widget_id]['callback'] = array($this, 'replace_widget_output');
163 }
164 }
165 }
166
167
168 function replace_widget_output() {
169 global $wp_registered_widgets;
170
171 $all_params = func_get_args();
172
173 if (is_array($all_params[2]))
174 $widget_id = $all_params[2]['widget_id'];
175 else
176 $widget_id = $all_params[1]['widget_id'];
177
178 $widget_callback = $wp_registered_widgets[$widget_id]['callback_original_wc'];
179
180 if (is_callable($widget_callback)) {
181 call_user_func_array($widget_callback, $all_params);
182 return true;
183 } elseif (!is_callable($widget_callback)) {
184 // print_r($all_params);
185 print '<!-- widget context: could not call the original callback function -->';
186 return false;
187 } else {
188 return false;
189 }
190 }
191
192
193 function replace_widget_control_callback() {
194 global $wp_registered_widget_controls;
195
196 $all_params = func_get_args();
197 if (is_array($all_params[1]))
198 $widget_id = $all_params[1]['widget_id'];
199 else
200 $widget_id = $all_params[0]['widget_id'];
201
202 $original_callback = $wp_registered_widget_controls[$widget_id]['callback_original_wc'];
203
204 // Display the original callback
205 if (isset($original_callback) && is_callable($original_callback)) {
206 call_user_func_array($original_callback, $all_params);
207 } else {
208 print '<!-- widget context [controls]: could not call the original callback function -->';
209 }
210
211 print $this->display_widget_context($original_callback, $widget_id);
212 }
213
214
215 function get_current_url() {
216 if ($_SERVER['REQUEST_URI'] == '')
217 $uri = $_SERVER['REDIRECT_URL'];
218 else
219 $uri = $_SERVER['REQUEST_URI'];
220
221 $url = (!empty($_SERVER['HTTPS']))
222 ? "https://".$_SERVER['SERVER_NAME'].$uri
223 : "http://".$_SERVER['SERVER_NAME'].$uri;
224
225 if (substr($url, -1) == '/')
226 $url = substr($url, 0, -1);
227
228 return $url;
229 }
230
231 // Thanks to Drupal: http://api.drupal.org/api/function/drupal_match_path/6
232 function match_path($path, $patterns) {
233 static $regexps;
234
235 // get home url;
236 $home_url = get_bloginfo('url');
237
238 // add trailing slash if missing
239 if (substr($home_url, -1) !== '/')
240 $home_url = $home_url . '/';
241
242 // Check if user has specified the absolute url
243 // else strip home url and check only REQUEST_URI part
244 if ($path !== $home_url && !strstr($patterns, $_SERVER['SERVER_NAME']))
245 $path = str_replace($home_url, '', $path);
246
247 // Remove http:// from the url user has specified
248 if (strstr($patterns, 'http://'))
249 $patterns = str_replace('http://', '', $patterns);
250
251 // Remove http:// from the current url
252 if (strstr($path, 'http://'))
253 $path = str_replace('http://', '', $path);
254
255 if (!isset($regexps[$patterns])) {
256 $regexps[$patterns] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<home\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote($home_url, '/') .'\2'), preg_quote($patterns, '/')) .')$/';
257 }
258 return preg_match($regexps[$patterns], $path);
259 }
260
261
262 function count_words_on_page() {
263 global $wp_query;
264
265 $this->words_on_page = 0;
266
267 if (count($wp_query->posts) > 0 && function_exists('strip_shortcodes')) {
268 foreach ($wp_query->posts as $pid => $post_data) {
269 if ($post_data->post_status == 'publish') {
270 $pure_content = strip_shortcodes($post_data->post_content);
271 if (!is_single() && !is_page()) {
272 if (preg_match('/<!--more(.*?)?-->/', $pure_content, $matches)) {
273 $pure_content = explode($matches[0], $pure_content, 2);
274 $words_in_post = str_word_count(strip_tags($pure_content[0]));
275 }
276 } else {
277 $words_in_post = str_word_count(strip_tags($pure_content));
278 }
279
280 $this->words_on_page += $words_in_post;
281 }
282 }
283 }
284 }
285
286 function check_widget_visibility($vis_settings = array()) {
287 global $paged;
288
289 if (empty($vis_settings))
290 return true;
291
292 $do_show = true;
293 $do_show_by_select = false;
294 $do_show_by_url = false;
295 $do_show_by_word_count = false;
296
297 // Check by current URL
298 if (!empty($vis_settings['url']['urls'])) {
299 // Split on line breaks
300 $split_urls = split("[\n ]+", (string)$vis_settings['url']['urls']);
301 $current_url = $this->get_current_url();
302 foreach ($split_urls as $id => $check_url) {
303 $check_url = trim($check_url);
304 if ($check_url !== '') {
305 if ($this->match_path($current_url, $check_url))
306 $do_show_by_url = true;
307 } else {
308 $ignore_url = true;
309 }
310 }
311
312 if (!$ignore_url && $do_show_by_url)
313 $do_show_by_url = true;
314 else
315 $do_show_by_url = false;
316 }
317
318 // Check by tag settings
319 if (!empty($vis_settings['location'])) {
320 $currently = array();
321
322 if (is_front_page() && $paged < 2) $currently['is_front_page'] = true;
323 if (is_home() && $paged < 2) $currently['is_home'] = true;
324 if (is_page() && !is_attachment()) $currently['is_page'] = true;
325 if (is_single() && !is_attachment()) $currently['is_single'] = true;
326 if (is_archive()) $currently['is_archive'] = true;
327 if (is_category()) $currently['is_category'] = true;
328 if (is_tag()) $currently['is_tag'] = true;
329 if (is_author()) $currently['is_author'] = true;
330 if (is_search()) $currently['is_search'] = true;
331 if (is_404()) $currently['is_404'] = true;
332 if (is_attachment()) $currently['is_attachment'] = true;
333
334 // Check for selected pages/sections
335 $current_location = array_keys($currently);
336 $visibility_options = array_keys($vis_settings['location']);
337 foreach($current_location as $location_id) {
338 if (in_array($location_id, $visibility_options))
339 $do_show_by_select = true;
340 }
341
342 // Check for word count
343 $word_count_to_check = (int)$vis_settings['location']['word_count'];
344
345 if ($vis_settings['location']['check_wordcount'] == 'on' && $word_count_to_check > 1) {
346 $check_type = $vis_settings['location']['check_wordcount_type'];
347
348 if (($check_type == 'more') && ($this->words_on_page > $word_count_to_check)) {
349 print '<!-- showing because '. $this->words_on_page .' > '. $word_count_to_check .' -->';
350 $do_show_by_word_count = true;
351 } elseif (($check_type == 'less') && ($this->words_on_page < $word_count_to_check)) {
352 print '<!-- showing because '. $this->words_on_page .' < '. $word_count_to_check .' -->';
353 $do_show_by_word_count = true;
354 }
355 } else {
356 $ignore_word_count = true;
357 }
358
359 if (!$ignore_word_count && $do_show_by_word_count)
360 $do_show_by_word_count = true;
361 else
362 $do_show_by_word_count = false;
363
364 }
365
366 // Combine all context checks
367 if ($do_show_by_word_count || $do_show_by_url || $do_show_by_select)
368 $one_is_true = true;
369 elseif (!$do_show_by_word_count || !$do_show_by_url || !$do_show_by_select)
370 $one_is_true = false;
371
372
373 if (($vis_settings['incexc'] == 'selected') && $one_is_true) {
374 // Show on selected
375 $do_show = true;
376 } elseif (($vis_settings['incexc'] == 'notselected') && !$one_is_true) {
377 // Hide on selected
378 $do_show = true;
379 } elseif (!empty($vis_settings['incexc'])) {
380 $do_show = false;
381 } else {
382 $do_show = true;
383 }
384
385 // Hide if selected
386 if ($vis_settings['incexc'] == 'hide') {
387 $do_show = false;
388 }
389
390 return $do_show;
391 }
392
393
394 function display_widget_context($args = array(), $wid = null) {
395
396 $group = 'location'; // Produces: wl[$wid][$group][homepage/singlepost/...]
397 $options = get_option($this->options_name);
398
399 $out = '<div class="widget-context"><div class="widget-context-inside">';
400 $out .= '<div class="wl-header"><h5>Widget Context:</h5>'
401 . '<p class="wl-visibility">'
402 . $this->make_simple_radio($options, $wid, 'incexc', 'selected', '<strong>Show</strong> on selected')
403 . $this->make_simple_radio($options, $wid, 'incexc', 'notselected', '<strong>Hide</strong> on selected')
404 . $this->make_simple_radio($options, $wid, 'incexc', 'hide', 'Hide')
405 . '</p></div>'
406
407 . $this->show_support() // you can comment out this line, if you want.
408
409 . '<div class="wl-wrap-columns">'
410
411 . '<div class="wl-columns">'
412 . '<div class="wl-column-2-1"><p>'
413 . $this->make_simple_checkbox($options, $wid, $group, 'is_front_page', __('Front Page'))
414 . $this->make_simple_checkbox($options, $wid, $group, 'is_home', __('Blog Index'))
415 . $this->make_simple_checkbox($options, $wid, $group, 'is_single', __('Single Post'))
416 . $this->make_simple_checkbox($options, $wid, $group, 'is_page', __('Single Page'))
417 . $this->make_simple_checkbox($options, $wid, $group, 'is_attachment', __('Attachment'))
418 . $this->make_simple_checkbox($options, $wid, $group, 'is_search', __('Search'))
419 . '</p></div>'
420 . '<div class="wl-column-2-2"><p>'
421 . $this->make_simple_checkbox($options, $wid, $group, 'is_archive', __('All Archives'))
422 . $this->make_simple_checkbox($options, $wid, $group, 'is_category', __('Category Archive'))
423 . $this->make_simple_checkbox($options, $wid, $group, 'is_tag', __('Tag Archive'))
424 . $this->make_simple_checkbox($options, $wid, $group, 'is_author', __('Author Archive'))
425 . $this->make_simple_checkbox($options, $wid, $group, 'is_404', __('404 Error'))
426 . '</p></div>'
427
428 . '<div class="wl-word-count"><p>'
429 . $this->make_simple_checkbox($options, $wid, $group, 'check_wordcount', __('Has'))
430 . $this->make_simple_dropdown($options, $wid, $group, 'check_wordcount_type', array('less' => __('less'), 'more' => __('more')), '', __('than'))
431 . $this->make_simple_textfield($options, $wid, $group, 'word_count', null, __('words'))
432 . '</p></div>'
433
434 . '</div>'
435
436 . '<div class="wl-options">'
437 . $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.'))
438 . '</div>'
439
440 . '</div>'
441
442 . $this->make_simple_textarea($options, $wid, 'general', 'notes', __('Notes (invisible to public)'))
443 . '</div></div>';
444
445 return $out;
446 }
447
448 function printAdminOptions() {
449 global $wp_registered_widget_controls, $wp_registered_widgets;
450
451 print '<div class="wrap"><h2>'.__('Widget Context Plugin Settings') . '</h2></div>';
452 print '<pre>'; print_r(get_option($this->options_name)); print '</pre>';
453 }
454
455
456
457 /*
458
459 Interface constructors
460
461 */
462
463 function show_support() {
464 $out = '';
465 if (rand(1,3) == 1)
466 $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>';
467
468 return $out;
469 }
470
471 function makeSubmitButton() {
472 return '<p class="submit"><input type="submit" name="Submit" value="' . __('Save Options') . '" /></p>';
473 }
474
475 function make_simple_checkbox($options, $prefix, $id, $fieldname = null, $label) {
476 if ($fieldname !== null) {
477 $value = strip_tags($options[$prefix][$id][$fieldname]);
478 $fieldname = '[' . $fieldname . ']';
479 } else {
480 $value = strip_tags($options[$prefix][$id]);
481 $fieldname = '';
482 }
483
484 $prefix = '[' . $prefix . ']';
485 $id = '[' . $id . ']';
486
487 if (!empty($value)) {
488 $value = 1; $checked = 'checked="checked"'; $classname = 'wl-active';
489 } else {
490 $value = 0; $checked = ''; $classname = 'wl-inactive';
491 }
492
493 $out = '<label class="' . $classname . '"><input type="checkbox" name="wl'. $prefix . $id . $fieldname . '" '. $checked .' />&nbsp;'
494 . $label . '</label> ';
495
496 return $out;
497 }
498
499 function make_simple_textarea($options, $prefix, $id, $fieldname = null, $label, $tip = null) {
500 $classname = $fieldname;
501
502 if ($fieldname !== null) {
503 $value = $options[$prefix][$id][$fieldname];
504 $fieldname = '[' . $fieldname . ']';
505 } else {
506 $value = $options[$prefix][$id];
507 $fieldname = '';
508 }
509 $prefix = '[' . $prefix . ']';
510 $id = '[' . $id . ']';
511
512 if ($tip !== null) $tip = '<p class="wl-tip">' . $tip . '</p>';
513
514 $out = '<div class="wl-'. $classname .'">'
515 . '<label for="wl'. $prefix . $id . $fieldname . '"><strong>' . $label . '</strong></label>'
516 . '<textarea name="wl'. $prefix . $id . $fieldname . '" id="wl'. $prefix . $id . $fieldname . '">'. stripslashes($value) .'</textarea>'
517 . $tip . '</div>';
518 return $out;
519 }
520
521 function make_simple_textfield($options, $prefix, $id, $fieldname = null, $label_before = null, $label_after = null) {
522 $classname = $fieldname;
523
524 if ($fieldname !== null) {
525 $value = $options[$prefix][$id][$fieldname];
526 $fieldname = '[' . $fieldname . ']';
527 } else {
528 $value = $options[$prefix][$id];
529 $fieldname = '';
530 }
531 $prefix = '[' . $prefix . ']';
532 $id = '[' . $id . ']';
533
534 return '<label class="wl-'. $classname . '">' . $label_before . ' '
535 . '<input type="text" name="wl'. $prefix . $id . $fieldname . '" value="'. $value .'" /> '
536 . $label_after . '</label>';
537 }
538
539 function make_simple_radio($options, $id, $fieldname, $value, $label = null) {
540 if ($options[$id][$fieldname] == $value) {
541 $checked = 'checked="checked"'; $classname = 'wl-active';
542 } else {
543 $checked = ''; $classname = 'wl-inactive';
544 }
545
546 $id = '[' . $id . ']';
547 $fieldname = '[' . $fieldname . ']';
548
549 $out = '<label class="' . $classname . ' label-'. $value .'"><input type="radio" name="wl'. $id . $fieldname . '" value="'. $value .'" '. $checked .' /> '
550 . $label . '</label>';
551
552 return $out;
553 }
554
555 function make_simple_dropdown($options, $prefix, $id, $fieldname = null, $selection = array(), $label_before = null, $label_after = null) {
556 $classname = $fieldname;
557
558 if ($fieldname !== null) {
559 $value = $options[$prefix][$id][$fieldname];
560 $fieldname = '[' . $fieldname . ']';
561 } else {
562 $value = $options[$prefix][$id];
563 $fieldname = '';
564 }
565 $prefix = '[' . $prefix . ']';
566 $id = '[' . $id . ']';
567
568 $list = '<label class="wl-'. $classname .'"><select name="wl'. $prefix . $id . $fieldname . '">'
569 . $label_before . ' ';
570
571 if (!empty($selection)) {
572 foreach ($selection as $sid => $svalue) {
573 if ($value == $sid) {
574 $selected = 'selected="selected"';
575 } else {
576 $selected = '';
577 }
578
579 $list .= '<option value="' . $sid . '" ' . $selected . '>' . $svalue . '</option>';
580 }
581 } else {
582 $list .= '<option value="error" selected="selected">'. __('No options given') .'</option>';
583 }
584
585 $list .= '</select> ' . $label_after . '</label>';
586
587 return $list;
588 }
589 }
590
591 ?>