PluginProbe
Widget Context / 0.4.5
Widget Context v0.4.5
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.5, at widget-context.php

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