PluginProbe
Widget Context / 0.4.3
Widget Context v0.4.3
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.4.3, at widget-context.php

556 lines 19.3 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.4.3
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
72 return $sidebars_widgets;
73 }
74
75
76 function save_widget_context() {
77 global $wp_registered_widgets;
78
79 if (empty($_POST['widget-id']))
80 $_POST['widget-id'] = array();
81
82 if (isset($_POST['sidebar']) && !empty($_POST['sidebar']))
83 $sidebar_id = strip_tags((string)$_POST['sidebar']);
84 else
85 return;
86
87 // Load widget context settings
88 $options = get_option($this->options_name);
89
90 // Delete
91 if (isset($_POST['delete_widget']) && $_POST['delete_widget']) {
92 $del_id = $_POST['widget-id'];
93 unset($options[$del_id]);
94 }
95
96 $new_widget_context_settings = array_values($_POST['wl']);
97
98 // Add/Update
99 foreach($new_widget_context_settings as $widget_id => $widget_context) {
100 if (empty($widget_context))
101 $widget_context = array();
102 // If neither type of widget logic behaviour is selected, set to default
103 if (!isset($widget_context['incexc']))
104 $widget_context['incexc'] = 'notselected';
105
106 $options[(string)$_POST['widget-id']] = $widget_context;
107 }
108
109 update_option($this->options_name, (array)$options);
110
111 return;
112 }
113
114
115 function attach_widget_context_controls() {
116 global $wp_registered_widget_controls, $wp_registered_widgets;
117
118 foreach ($wp_registered_widgets as $widget_id => $widget_data) {
119 // Pass widget id as param, so that we can later call the original callback function
120 $wp_registered_widget_controls[$widget_id]['params'][]['widget_id'] = $widget_id;
121 // Store the original callback functions and replace them with Widget Context
122 $wp_registered_widget_controls[$widget_id]['callback_original_wc'] = $wp_registered_widget_controls[$widget_id]['callback'];
123 $wp_registered_widget_controls[$widget_id]['callback'] = array($this, 'replace_widget_control_callback');
124 }
125 }
126
127
128 function replace_widget_output_callback() {
129 global $wp_registered_widgets;
130
131 foreach ($wp_registered_widgets as $widget_id => $widget_data) {
132 //if (!$wp_registered_widgets[$widget_id]['params'][0]['widget_id']) {
133 // Save the original widget id
134 $wp_registered_widgets[$widget_id]['params'][]['widget_id'] = $widget_id;
135 // Store original widget callbacks
136 $wp_registered_widgets[$widget_id]['callback_original_wc'] = $wp_registered_widgets[$widget_id]['callback'];
137 $wp_registered_widgets[$widget_id]['callback'] = array($this, 'replace_widget_output');
138 //}
139 }
140 }
141
142
143 function replace_widget_output() {
144 global $wp_registered_widgets;
145
146 $all_params = func_get_args();
147
148 $widget_id = $all_params[2]['widget_id'];
149 $widget_callback = $wp_registered_widgets[$widget_id]['callback_original_wc'];
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 $do_show = $this->check_widget_visibility($this->context_options[$widget_id]);
156
157 if (is_callable($widget_callback) && $do_show) {
158 call_user_func_array($widget_callback, $all_params);
159 return true;
160 } elseif (!is_callable($widget_callback)) {
161 // print_r($all_params);
162 print '<!-- widget context: could not call the original callback function -->';
163 return false;
164 } else {
165 return false;
166 }
167 }
168
169
170 function replace_widget_control_callback() {
171 global $wp_registered_widget_controls;
172
173 $all_params = func_get_args();
174
175 $widget_id = $all_params[1]['widget_id'];
176 $original_callback = $wp_registered_widget_controls[$widget_id]['callback_original_wc'];
177
178 // Display the original callback
179 if (isset($original_callback) && is_callable($original_callback)) {
180 call_user_func_array($original_callback, $all_params);
181 } else {
182 print '<!-- widget context [controls]: could not call the original callback function -->';
183 }
184
185 print $this->display_widget_context($original_callback, $all_params);
186 }
187
188
189 function get_current_url() {
190 if ($_SERVER['REQUEST_URI'] == '')
191 $uri = $_SERVER['REDIRECT_URL'];
192 else
193 $uri = $_SERVER['REQUEST_URI'];
194
195 $url = (!empty($_SERVER['HTTPS']))
196 ? "https://".$_SERVER['SERVER_NAME'].$uri
197 : "http://".$_SERVER['SERVER_NAME'].$uri;
198
199 if (substr($url, -1) == '/')
200 $url = substr($url, 0, -1);
201
202 return $url;
203 }
204
205 // Thanks to Drupal: http://api.drupal.org/api/function/drupal_match_path/6
206 function match_path($path, $patterns) {
207 static $regexps;
208
209 // get home url;
210 $home_url = get_bloginfo('url');
211
212 // add trailing slash if missing
213 if (substr($home_url, -1) !== '/')
214 $home_url = $home_url . '/';
215
216 // if not at home, remove home path from current path
217 if ($path !== $home_url)
218 $path = str_replace($home_url, '', $path);
219
220 if (!isset($regexps[$patterns])) {
221 $regexps[$patterns] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<home\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote($home_url, '/') .'\2'), preg_quote($patterns, '/')) .')$/';
222 }
223 return preg_match($regexps[$patterns], $path);
224 }
225
226
227 function count_words_on_page() {
228 global $wp_query;
229
230 $this->words_on_page = 0;
231
232 if (count($wp_query->posts) > 0 && function_exists('strip_shortcodes')) {
233 foreach ($wp_query->posts as $pid => $post_data) {
234 if ($post_data->post_status == 'publish') {
235 $pure_content = strip_shortcodes($post_data->post_content);
236 if (!is_single() && !is_page()) {
237 if (preg_match('/<!--more(.*?)?-->/', $pure_content, $matches)) {
238 $pure_content = explode($matches[0], $pure_content, 2);
239 $words_in_post = str_word_count(strip_tags($pure_content[0]));
240 }
241 } else {
242 $words_in_post = str_word_count(strip_tags($pure_content));
243 }
244
245 $this->words_on_page += $words_in_post;
246 }
247 }
248 }
249 }
250
251 function check_widget_visibility($vis_settings = array()) {
252 global $paged;
253
254 if (empty($vis_settings))
255 return true;
256
257 $do_show = true;
258 $do_show_by_select = false;
259 $do_show_by_url = false;
260 $do_show_by_word_count = false;
261
262 // Check by current URL
263 if (!empty($vis_settings['url']['urls'])) {
264 // Split on line breaks
265 $split_urls = split("[\n ]+", (string)$vis_settings['url']['urls']);
266 $current_url = $this->get_current_url();
267 foreach ($split_urls as $id => $check_url) {
268 $check_url = trim($check_url);
269 if ($check_url !== '') {
270 if ($this->match_path($current_url, $check_url))
271 $do_show_by_url = true;
272 } else {
273 $ignore_url = true;
274 }
275 }
276
277 if (!$ignore_url && $do_show_by_url)
278 $do_show_by_url = true;
279 else
280 $do_show_by_url = false;
281 }
282
283 // Check by tag settings
284 if (!empty($vis_settings['location'])) {
285 $currently = array();
286
287 if ((is_front_page() || is_home()) && $paged < 2 && !is_404()) $currently['is_front_page'] = true;
288 if (is_page() && !is_attachment()) $currently['is_page'] = true;
289 if (is_single() && !is_attachment()) $currently['is_single'] = true;
290 if (is_archive()) $currently['is_archive'] = true;
291 if (is_category()) $currently['is_category'] = true;
292 if (is_tag()) $currently['is_tag'] = true;
293 if (is_author()) $currently['is_author'] = true;
294 if (is_search()) $currently['is_search'] = true;
295 if (is_404()) $currently['is_404'] = true;
296 if (is_attachment()) $currently['is_attachment'] = true;
297
298 // Check for selected pages/sections
299 $current_location = array_keys($currently);
300 $visibility_options = array_keys($vis_settings['location']);
301 foreach($current_location as $location_id) {
302 if (in_array($location_id, $visibility_options))
303 $do_show_by_select = true;
304 }
305
306 // Check for word count
307 $word_count_to_check = (int)$vis_settings['location']['word_count'];
308
309 if ($vis_settings['location']['check_wordcount'] == 'on' && $word_count_to_check > 1) {
310 $check_type = $vis_settings['location']['check_wordcount_type'];
311
312 if (($check_type == 'more') && ($this->words_on_page > $word_count_to_check)) {
313 print '<!-- showing because '. $this->words_on_page .' > '. $word_count_to_check .' -->';
314 $do_show_by_word_count = true;
315 } elseif (($check_type == 'less') && ($this->words_on_page < $word_count_to_check)) {
316 print '<!-- showing because '. $this->words_on_page .' < '. $word_count_to_check .' -->';
317 $do_show_by_word_count = true;
318 }
319 } else {
320 $ignore_word_count = true;
321 }
322
323 if (!$ignore_word_count && $do_show_by_word_count)
324 $do_show_by_word_count = true;
325 else
326 $do_show_by_word_count = false;
327
328 }
329
330 // Combine all context checks
331 if ($do_show_by_word_count || $do_show_by_url || $do_show_by_select)
332 $one_is_true = true;
333 elseif (!$do_show_by_word_count || !$do_show_by_url || !$do_show_by_select)
334 $one_is_true = false;
335
336
337 if (($vis_settings['incexc'] == 'selected') && $one_is_true) {
338 // Show on selected
339 $do_show = true;
340 } elseif (($vis_settings['incexc'] == 'notselected') && !$one_is_true) {
341 // Hide on selected
342 $do_show = true;
343 } elseif (!empty($vis_settings['incexc'])) {
344 $do_show = false;
345 } else {
346 $do_show = true;
347 }
348
349 // Hide if selected
350 if ($vis_settings['incexc'] == 'hide') {
351 $do_show = false;
352 }
353
354 return $do_show;
355 }
356
357
358 function display_widget_context($args = array(), $params = array()) {
359
360 $wid = $params[1]['widget_id'];
361
362 $group = 'location'; // Produces: wl[$wid][$group][homepage/singlepost/...]
363 $options = get_option($this->options_name);
364
365 $out = '<div class="widget-context"><div class="widget-context-inside">';
366 $out .= '<div class="wl-header"><h5>Widget Context:</h5>'
367 . '<p class="wl-visibility">'
368 . $this->make_simple_radio($options, $wid, 'incexc', 'selected', '<strong>Show</strong> on selected')
369 . $this->make_simple_radio($options, $wid, 'incexc', 'notselected', '<strong>Hide</strong> on selected')
370 . $this->make_simple_radio($options, $wid, 'incexc', 'hide', 'Hide')
371 . '</p></div>'
372
373 . $this->show_support() // you can comment out this line, if you want.
374
375 . '<div class="wl-wrap-columns">'
376
377 . '<div class="wl-columns">'
378 . '<div class="wl-column-2-1"><p>'
379 . $this->make_simple_checkbox($options, $wid, $group, 'is_front_page', __('Homepage'))
380 . $this->make_simple_checkbox($options, $wid, $group, 'is_single', __('Single Post'))
381 . $this->make_simple_checkbox($options, $wid, $group, 'is_page', __('Single Page'))
382 . $this->make_simple_checkbox($options, $wid, $group, 'is_attachment', __('Attachment'))
383 . $this->make_simple_checkbox($options, $wid, $group, 'is_search', __('Search'))
384 . '</p></div>'
385 . '<div class="wl-column-2-2"><p>'
386 . $this->make_simple_checkbox($options, $wid, $group, 'is_archive', __('All Archives'))
387 . $this->make_simple_checkbox($options, $wid, $group, 'is_category', __('Category Archive'))
388 . $this->make_simple_checkbox($options, $wid, $group, 'is_tag', __('Tag Archive'))
389 . $this->make_simple_checkbox($options, $wid, $group, 'is_author', __('Author Archive'))
390 . $this->make_simple_checkbox($options, $wid, $group, 'is_404', __('404 Error'))
391 . '</p></div>'
392
393 . '<div class="wl-word-count"><p>'
394 . $this->make_simple_checkbox($options, $wid, $group, 'check_wordcount', __('Has'))
395 . $this->make_simple_dropdown($options, $wid, $group, 'check_wordcount_type', array('less' => __('less'), 'more' => __('more')), '', __('than'))
396 . $this->make_simple_textfield($options, $wid, $group, 'word_count', null, __('words'))
397 . '</p></div>'
398
399 . '</div>'
400
401 . '<div class="wl-options">'
402 . $this->make_simple_textarea($options, $wid, 'url', 'urls', __('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.'))
403 . '</div>'
404
405 . '</div>'
406
407 . $this->make_simple_textarea($options, $wid, 'general', 'notes', __('Notes (invisible to public)'))
408 . '</div></div>';
409
410 return $out;
411 }
412
413 function printAdminOptions() {
414 global $wp_registered_widget_controls, $wp_registered_widgets;
415
416 print '<div class="wrap"><h2>'.__('Widget Context Plugin Settings') . '</h2></div>';
417 print '<pre>'; print_r(get_option($this->options_name)); print '</pre>';
418 }
419
420
421
422 /*
423
424 Interface constructors
425
426 */
427
428 function show_support() {
429 $out = '';
430 if (rand(1,3) == 1)
431 $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>';
432
433 return $out;
434 }
435
436 function makeSubmitButton() {
437 return '<p class="submit"><input type="submit" name="Submit" value="' . __('Save Options') . '" /></p>';
438 }
439
440 function make_simple_checkbox($options, $prefix, $id, $fieldname = null, $label) {
441 if ($fieldname !== null) {
442 $value = strip_tags($options[$prefix][$id][$fieldname]);
443 $fieldname = '[' . $fieldname . ']';
444 } else {
445 $value = strip_tags($options[$prefix][$id]);
446 $fieldname = '';
447 }
448
449 $prefix = '[' . $prefix . ']';
450 $id = '[' . $id . ']';
451
452 if (!empty($value)) {
453 $value = 1; $checked = 'checked="checked"'; $classname = 'wl-active';
454 } else {
455 $value = 0; $checked = ''; $classname = 'wl-inactive';
456 }
457
458 $out = '<label class="' . $classname . '"><input type="checkbox" name="wl'. $prefix . $id . $fieldname . '" '. $checked .' />&nbsp;'
459 . $label . '</label> ';
460
461 return $out;
462 }
463
464 function make_simple_textarea($options, $prefix, $id, $fieldname = null, $label, $tip = null) {
465 $classname = $fieldname;
466
467 if ($fieldname !== null) {
468 $value = $options[$prefix][$id][$fieldname];
469 $fieldname = '[' . $fieldname . ']';
470 } else {
471 $value = $options[$prefix][$id];
472 $fieldname = '';
473 }
474 $prefix = '[' . $prefix . ']';
475 $id = '[' . $id . ']';
476
477 if ($tip !== null) $tip = '<p class="wl-tip">' . $tip . '</p>';
478
479 $out = '<div class="wl-'. $classname .'">'
480 . '<label for="wl'. $prefix . $id . $fieldname . '"><strong>' . $label . '</strong></label>'
481 . '<textarea name="wl'. $prefix . $id . $fieldname . '" id="wl'. $prefix . $id . $fieldname . '">'. stripslashes($value) .'</textarea>'
482 . $tip . '</div>';
483 return $out;
484 }
485
486 function make_simple_textfield($options, $prefix, $id, $fieldname = null, $label_before = null, $label_after = null) {
487 $classname = $fieldname;
488
489 if ($fieldname !== null) {
490 $value = $options[$prefix][$id][$fieldname];
491 $fieldname = '[' . $fieldname . ']';
492 } else {
493 $value = $options[$prefix][$id];
494 $fieldname = '';
495 }
496 $prefix = '[' . $prefix . ']';
497 $id = '[' . $id . ']';
498
499 return '<label class="wl-'. $classname . '">' . $label_before . ' '
500 . '<input type="text" name="wl'. $prefix . $id . $fieldname . '" value="'. $value .'" /> '
501 . $label_after . '</label>';
502 }
503
504 function make_simple_radio($options, $id, $fieldname, $value, $label = null) {
505 if ($options[$id][$fieldname] == $value) {
506 $checked = 'checked="checked"'; $classname = 'wl-active';
507 } else {
508 $checked = ''; $classname = 'wl-inactive';
509 }
510
511 $id = '[' . $id . ']';
512 $fieldname = '[' . $fieldname . ']';
513
514 $out = '<label class="' . $classname . ' label-'. $value .'"><input type="radio" name="wl'. $id . $fieldname . '" value="'. $value .'" '. $checked .' /> '
515 . $label . '</label>';
516
517 return $out;
518 }
519
520 function make_simple_dropdown($options, $prefix, $id, $fieldname = null, $selection = array(), $label_before = null, $label_after = null) {
521 $classname = $fieldname;
522
523 if ($fieldname !== null) {
524 $value = $options[$prefix][$id][$fieldname];
525 $fieldname = '[' . $fieldname . ']';
526 } else {
527 $value = $options[$prefix][$id];
528 $fieldname = '';
529 }
530 $prefix = '[' . $prefix . ']';
531 $id = '[' . $id . ']';
532
533 $list = '<label class="wl-'. $classname .'"><select name="wl'. $prefix . $id . $fieldname . '">'
534 . $label_before . ' ';
535
536 if (!empty($selection)) {
537 foreach ($selection as $sid => $svalue) {
538 if ($value == $sid) {
539 $selected = 'selected="selected"';
540 } else {
541 $selected = '';
542 }
543
544 $list .= '<option value="' . $sid . '" ' . $selected . '>' . $svalue . '</option>';
545 }
546 } else {
547 $list .= '<option value="error" selected="selected">'. __('No options given') .'</option>';
548 }
549
550 $list .= '</select> ' . $label_after . '</label>';
551
552 return $list;
553 }
554 }
555
556 ?>