plugin_path = WP_CONTENT_URL . '/plugins/'. plugin_basename(dirname(__FILE__)) . '/'; // Amend widget controls with Widget Context controls add_action('sidebar_admin_setup', array($this, 'attach_widget_context_controls')); // Enable widget context check only when viewed publicly, add_action('wp_head', array($this, 'replace_widget_output_callback')); // Add admin menu for config // add_action('admin_menu', array($this, 'addAdminOptions')); add_action('admin_enqueue_scripts', array($this, 'adminCSS')); // Save widget context settings, when in admin area add_filter('sidebars_widgets', array($this, 'filter_widgets')); // Check the number of words on page add_action('wp_print_scripts', array($this, 'count_words_on_page'), 750); } function addAdminOptions() { // add_options_page('Widget Context', 'Widget Context', 10, basename(__FILE__), array($this, 'printAdminOptions')); } function adminCSS() { wp_enqueue_style('widget-context-admin', $this->plugin_path . 'admin-style.css'); } function filter_widgets($sidebars_widgets) { if (isset($_POST['wl']) && !empty($_POST['wl']) && is_admin()) { $this->save_widget_context(); unset($_POST['wl']); } return $sidebars_widgets; } function save_widget_context() { global $wp_registered_widgets; if (empty($_POST['widget-id'])) $_POST['widget-id'] = array(); if (isset($_POST['sidebar']) && !empty($_POST['sidebar'])) $sidebar_id = strip_tags((string)$_POST['sidebar']); else return; // Load widget context settings $options = get_option($this->options_name); // Delete if (isset($_POST['delete_widget']) && $_POST['delete_widget']) { $del_id = $_POST['widget-id']; unset($options[$del_id]); } $new_widget_context_settings = array_values($_POST['wl']); // Add/Update foreach($new_widget_context_settings as $widget_id => $widget_context) { if (empty($widget_context)) $widget_context = array(); // If neither type of widget logic behaviour is selected, set to default if (!isset($widget_context['incexc'])) $widget_context['incexc'] = 'notselected'; $options[(string)$_POST['widget-id']] = $widget_context; } update_option($this->options_name, (array)$options); return; } function attach_widget_context_controls() { global $wp_registered_widget_controls, $wp_registered_widgets; foreach ($wp_registered_widgets as $widget_id => $widget_data) { // Pass widget id as param, so that we can later call the original callback function $wp_registered_widget_controls[$widget_id]['params'][]['widget_id'] = $widget_id; // Store the original callback functions and replace them with Widget Context $wp_registered_widget_controls[$widget_id]['callback_original_wc'] = $wp_registered_widget_controls[$widget_id]['callback']; $wp_registered_widget_controls[$widget_id]['callback'] = array($this, 'replace_widget_control_callback'); } } function replace_widget_output_callback() { global $wp_registered_widgets; foreach ($wp_registered_widgets as $widget_id => $widget_data) { //if (!$wp_registered_widgets[$widget_id]['params'][0]['widget_id']) { // Save the original widget id $wp_registered_widgets[$widget_id]['params'][]['widget_id'] = $widget_id; // Store original widget callbacks $wp_registered_widgets[$widget_id]['callback_original_wc'] = $wp_registered_widgets[$widget_id]['callback']; $wp_registered_widgets[$widget_id]['callback'] = array($this, 'replace_widget_output'); //} } } function replace_widget_output() { global $wp_registered_widgets; $all_params = func_get_args(); if (is_array($all_params[2])) $widget_id = $all_params[2]['widget_id']; else $widget_id = $all_params[1]['widget_id']; $widget_callback = $wp_registered_widgets[$widget_id]['callback_original_wc']; // Get widget logic options and check visibility settings if (empty($this->context_options)) $this->context_options = get_option($this->options_name); $do_show = $this->check_widget_visibility($this->context_options[$widget_id]); if (is_callable($widget_callback) && $do_show) { call_user_func_array($widget_callback, $all_params); return true; } elseif (!is_callable($widget_callback)) { // print_r($all_params); print ''; return false; } else { return false; } } function replace_widget_control_callback() { global $wp_registered_widget_controls; $all_params = func_get_args(); if (is_array($all_params[1])) $widget_id = $all_params[1]['widget_id']; else $widget_id = $all_params[0]['widget_id']; $original_callback = $wp_registered_widget_controls[$widget_id]['callback_original_wc']; // Display the original callback if (isset($original_callback) && is_callable($original_callback)) { call_user_func_array($original_callback, $all_params); } else { print ''; } print $this->display_widget_context($original_callback, $widget_id); } function get_current_url() { if ($_SERVER['REQUEST_URI'] == '') $uri = $_SERVER['REDIRECT_URL']; else $uri = $_SERVER['REQUEST_URI']; $url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$uri : "http://".$_SERVER['SERVER_NAME'].$uri; if (substr($url, -1) == '/') $url = substr($url, 0, -1); return $url; } // Thanks to Drupal: http://api.drupal.org/api/function/drupal_match_path/6 function match_path($path, $patterns) { static $regexps; // get home url; $home_url = get_bloginfo('url'); // add trailing slash if missing if (substr($home_url, -1) !== '/') $home_url = $home_url . '/'; // if not at home, remove home path from current path if ($path !== $home_url) $path = str_replace($home_url, '', $path); if (!isset($regexps[$patterns])) { $regexps[$patterns] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\($|\|)/'), array('|', '.*', '\1'. preg_quote($home_url, '/') .'\2'), preg_quote($patterns, '/')) .')$/'; } return preg_match($regexps[$patterns], $path); } function count_words_on_page() { global $wp_query; $this->words_on_page = 0; if (count($wp_query->posts) > 0 && function_exists('strip_shortcodes')) { foreach ($wp_query->posts as $pid => $post_data) { if ($post_data->post_status == 'publish') { $pure_content = strip_shortcodes($post_data->post_content); if (!is_single() && !is_page()) { if (preg_match('//', $pure_content, $matches)) { $pure_content = explode($matches[0], $pure_content, 2); $words_in_post = str_word_count(strip_tags($pure_content[0])); } } else { $words_in_post = str_word_count(strip_tags($pure_content)); } $this->words_on_page += $words_in_post; } } } } function check_widget_visibility($vis_settings = array()) { global $paged; if (empty($vis_settings)) return true; $do_show = true; $do_show_by_select = false; $do_show_by_url = false; $do_show_by_word_count = false; // Check by current URL if (!empty($vis_settings['url']['urls'])) { // Split on line breaks $split_urls = split("[\n ]+", (string)$vis_settings['url']['urls']); $current_url = $this->get_current_url(); foreach ($split_urls as $id => $check_url) { $check_url = trim($check_url); if ($check_url !== '') { if ($this->match_path($current_url, $check_url)) $do_show_by_url = true; } else { $ignore_url = true; } } if (!$ignore_url && $do_show_by_url) $do_show_by_url = true; else $do_show_by_url = false; } // Check by tag settings if (!empty($vis_settings['location'])) { $currently = array(); if ((is_front_page() || is_home()) && $paged < 2 && !is_404()) $currently['is_front_page'] = true; if (is_page() && !is_attachment()) $currently['is_page'] = true; if (is_single() && !is_attachment()) $currently['is_single'] = true; if (is_archive()) $currently['is_archive'] = true; if (is_category()) $currently['is_category'] = true; if (is_tag()) $currently['is_tag'] = true; if (is_author()) $currently['is_author'] = true; if (is_search()) $currently['is_search'] = true; if (is_404()) $currently['is_404'] = true; if (is_attachment()) $currently['is_attachment'] = true; // Check for selected pages/sections $current_location = array_keys($currently); $visibility_options = array_keys($vis_settings['location']); foreach($current_location as $location_id) { if (in_array($location_id, $visibility_options)) $do_show_by_select = true; } // Check for word count $word_count_to_check = (int)$vis_settings['location']['word_count']; if ($vis_settings['location']['check_wordcount'] == 'on' && $word_count_to_check > 1) { $check_type = $vis_settings['location']['check_wordcount_type']; if (($check_type == 'more') && ($this->words_on_page > $word_count_to_check)) { print ''; $do_show_by_word_count = true; } elseif (($check_type == 'less') && ($this->words_on_page < $word_count_to_check)) { print ''; $do_show_by_word_count = true; } } else { $ignore_word_count = true; } if (!$ignore_word_count && $do_show_by_word_count) $do_show_by_word_count = true; else $do_show_by_word_count = false; } // Combine all context checks if ($do_show_by_word_count || $do_show_by_url || $do_show_by_select) $one_is_true = true; elseif (!$do_show_by_word_count || !$do_show_by_url || !$do_show_by_select) $one_is_true = false; if (($vis_settings['incexc'] == 'selected') && $one_is_true) { // Show on selected $do_show = true; } elseif (($vis_settings['incexc'] == 'notselected') && !$one_is_true) { // Hide on selected $do_show = true; } elseif (!empty($vis_settings['incexc'])) { $do_show = false; } else { $do_show = true; } // Hide if selected if ($vis_settings['incexc'] == 'hide') { $do_show = false; } return $do_show; } function display_widget_context($args = array(), $wid = null) { $group = 'location'; // Produces: wl[$wid][$group][homepage/singlepost/...] $options = get_option($this->options_name); $out = '
'; $out .= '
Widget Context:
' . '

' . $this->make_simple_radio($options, $wid, 'incexc', 'selected', 'Show on selected') . $this->make_simple_radio($options, $wid, 'incexc', 'notselected', 'Hide on selected') . $this->make_simple_radio($options, $wid, 'incexc', 'hide', 'Hide') . '

' . $this->show_support() // you can comment out this line, if you want. . '
' . '
' . '

' . $this->make_simple_checkbox($options, $wid, $group, 'is_front_page', __('Homepage')) . $this->make_simple_checkbox($options, $wid, $group, 'is_single', __('Single Post')) . $this->make_simple_checkbox($options, $wid, $group, 'is_page', __('Single Page')) . $this->make_simple_checkbox($options, $wid, $group, 'is_attachment', __('Attachment')) . $this->make_simple_checkbox($options, $wid, $group, 'is_search', __('Search')) . '

' . '

' . $this->make_simple_checkbox($options, $wid, $group, 'is_archive', __('All Archives')) . $this->make_simple_checkbox($options, $wid, $group, 'is_category', __('Category Archive')) . $this->make_simple_checkbox($options, $wid, $group, 'is_tag', __('Tag Archive')) . $this->make_simple_checkbox($options, $wid, $group, 'is_author', __('Author Archive')) . $this->make_simple_checkbox($options, $wid, $group, 'is_404', __('404 Error')) . '

' . '

' . $this->make_simple_checkbox($options, $wid, $group, 'check_wordcount', __('Has')) . $this->make_simple_dropdown($options, $wid, $group, 'check_wordcount_type', array('less' => __('less'), 'more' => __('more')), '', __('than')) . $this->make_simple_textfield($options, $wid, $group, 'word_count', null, __('words')) . '

' . '
' . '
' . $this->make_simple_textarea($options, $wid, 'url', 'urls', __('Target by URL'), __('Enter one location fragment per line. Use * character as a wildcard. Use <home> to select front page. Examples: category/peace/* to target all peace category posts; 2012/* to target articles written in year 2012.')) . '
' . '
' . $this->make_simple_textarea($options, $wid, 'general', 'notes', __('Notes (invisible to public)')) . '
'; return $out; } function printAdminOptions() { global $wp_registered_widget_controls, $wp_registered_widgets; print '

'.__('Widget Context Plugin Settings') . '

'; print '
'; print_r(get_option($this->options_name)); print '
'; } /* Interface constructors */ function show_support() { $out = ''; if (rand(1,3) == 1) $out = '

If you find Widget Context plugin useful, please donate a few silver coins to support the development. Thanks. Kaspars

'; return $out; } function makeSubmitButton() { return '

'; } function make_simple_checkbox($options, $prefix, $id, $fieldname = null, $label) { if ($fieldname !== null) { $value = strip_tags($options[$prefix][$id][$fieldname]); $fieldname = '[' . $fieldname . ']'; } else { $value = strip_tags($options[$prefix][$id]); $fieldname = ''; } $prefix = '[' . $prefix . ']'; $id = '[' . $id . ']'; if (!empty($value)) { $value = 1; $checked = 'checked="checked"'; $classname = 'wl-active'; } else { $value = 0; $checked = ''; $classname = 'wl-inactive'; } $out = ' '; return $out; } function make_simple_textarea($options, $prefix, $id, $fieldname = null, $label, $tip = null) { $classname = $fieldname; if ($fieldname !== null) { $value = $options[$prefix][$id][$fieldname]; $fieldname = '[' . $fieldname . ']'; } else { $value = $options[$prefix][$id]; $fieldname = ''; } $prefix = '[' . $prefix . ']'; $id = '[' . $id . ']'; if ($tip !== null) $tip = '

' . $tip . '

'; $out = '
' . '' . '' . $tip . '
'; return $out; } function make_simple_textfield($options, $prefix, $id, $fieldname = null, $label_before = null, $label_after = null) { $classname = $fieldname; if ($fieldname !== null) { $value = $options[$prefix][$id][$fieldname]; $fieldname = '[' . $fieldname . ']'; } else { $value = $options[$prefix][$id]; $fieldname = ''; } $prefix = '[' . $prefix . ']'; $id = '[' . $id . ']'; return ''; } function make_simple_radio($options, $id, $fieldname, $value, $label = null) { if ($options[$id][$fieldname] == $value) { $checked = 'checked="checked"'; $classname = 'wl-active'; } else { $checked = ''; $classname = 'wl-inactive'; } $id = '[' . $id . ']'; $fieldname = '[' . $fieldname . ']'; $out = ''; return $out; } function make_simple_dropdown($options, $prefix, $id, $fieldname = null, $selection = array(), $label_before = null, $label_after = null) { $classname = $fieldname; if ($fieldname !== null) { $value = $options[$prefix][$id][$fieldname]; $fieldname = '[' . $fieldname . ']'; } else { $value = $options[$prefix][$id]; $fieldname = ''; } $prefix = '[' . $prefix . ']'; $id = '[' . $id . ']'; $list = ''; return $list; } } ?>