/**
 * Restrict sidebar widgets
 *
 * See ctfw_sidebar_widget_compatible() for how this works.
 * admin-widgets.php uses CSS to show message to incompatible widgets.
 *
 * Note: This affects both saving and displaying of widgets.
 *
 * @since 0.9
 * @param array $sidebars_widgets
 * @return array Modified $sidebars_widgets
 */
function ctfw_restrict_sidebars_widgets($sidebars_widgets)
{
    // Theme supports this?
    if (!current_theme_supports('ctfw-sidebar-widget-restrictions')) {
        return $sidebars_widgets;
    }
    // Loop sidebars
    foreach ($sidebars_widgets as $sidebar_id => $widgets) {
        // Any widgets?
        if (empty($widgets)) {
            continue;
        }
        // Leave core sidebars like "Inactive" alone
        if (preg_match('/^wp_/', $sidebar_id)) {
            continue;
        }
        // Sidebar widget restrictions
        // (used for checking limit)
        $sidebar_widget_restrictions = ctfw_get_sidebar_widget_restrictions('sidebar_widget');
        $sidebar_limit = !empty($sidebar_widget_restrictions[$sidebar_id]['limit']) ? $sidebar_widget_restrictions[$sidebar_id]['limit'] : false;
        // Loop widgets in sidebar
        $widget_i = 0;
        foreach ($widgets as $widget_key => $widget) {
            $widget_i++;
            $remove = false;
            // Determine widget id of this instance
            $widget_id = substr($widget, 0, strrpos($widget, '-'));
            // chop -# instance off end
            // Remove if either disallows the other
            // Front-end only because this can cause JavaScript error with WordPress 3.9 Customizer when "Add a Widget" clicked
            // The user will always see "Not compatible" in widget editors until they remove, but will never show on frontend
            if (!is_admin() && !ctfw_sidebar_widget_compatible($sidebar_id, $widget_id)) {
                $remove = true;
            }
            // Remove if widget limit for sidebar has been reached
            // Front-end only since no warning shown and don't want re-arranging to cause loss
            if (!is_admin() && $sidebar_limit && $widget_i > $sidebar_limit) {
                $remove = true;
            }
            // Remove widget from sidebar
            if ($remove) {
                unset($sidebars_widgets[$sidebar_id][$widget_key]);
            }
        }
    }
    // Re-index so keys are 0, 1, 2, etc. (fill in the gaps from unset)
    if (isset($sidebars_widgets[$sidebar_id])) {
        $sidebars_widgets[$sidebar_id] = array_values($sidebars_widgets[$sidebar_id]);
    }
    // Return pruned array
    return $sidebars_widgets;
}
/**
 * Show widget incompatibility messages
 *
 * If a user drags a widget into a sidebar that it is not compatible with, a message is shown.
 * Also see admin-widgets.css, admin-widgets.js and widgets.php.
 *
 * Note: ctfw_restrict_sidebars_widgets() handles removing widgets from sidebars on both front-end
 * and back-end in case user does not.
 *
 * @since 0.9
 */
function ctfw_admin_restrict_widgets_css()
{
    // Theme supports this?
    if (!current_theme_supports('ctfw-sidebar-widget-restrictions')) {
        return;
    }
    // Current admin screen
    $screen = get_current_screen();
    // Widgets page or Customizer only
    if ('widgets' == $screen->base || 'customize' == $screen->base) {
        // Elements will be captured into these
        $form_elements = array();
        $message_elements = array();
        // Get all registered widgets
        $widgets = ctfw_get_registered_widgets();
        // Loop all sidebars
        $sidebars = wp_get_sidebars_widgets();
        foreach ($sidebars as $sidebar_id => $sidebar) {
            // Leave core sidebars like "Inactive" alone
            if (preg_match('/^wp_/', $sidebar_id)) {
                continue;
            }
            // Loop widgets
            foreach ($widgets as $widget_id) {
                // Check if sidebar and widget are not compatible
                if (!ctfw_sidebar_widget_compatible($sidebar_id, $widget_id)) {
                    // Appearance > Widgets
                    if ('widgets' == $screen->base) {
                        // Elements for hiding form and save button
                        $form_elements[] = "#{$sidebar_id} div[id*=_{$widget_id}-] .widget-content";
                        $form_elements[] = "#{$sidebar_id} div[id*=_{$widget_id}-] .widget-control-save";
                        // Element for showing message
                        $message_elements[] = "#{$sidebar_id} div[id*=_{$widget_id}-] .ctfw-widget-incompatible";
                    } elseif ('customize' == $screen->base) {
                        // Elements for hiding form and save button
                        $form_elements[] = "#accordion-section-sidebar-widgets-{$sidebar_id} div[id*=_{$widget_id}-] .widget-content";
                        $form_elements[] = "#accordion-section-sidebar-widgets-{$sidebar_id} div[id*=_{$widget_id}-] .widget-control-save";
                        // Element for showing message
                        $message_elements[] = "#accordion-section-sidebar-widgets-{$sidebar_id} div[id*=_{$widget_id}-] .ctfw-widget-incompatible";
                    }
                }
            }
        }
        // Output stylesheet
        if (!empty($form_elements) && !empty($message_elements)) {
            // Compile elements
            $form_elements = implode(",\n", $form_elements);
            $message_elements = implode(",\n", $message_elements);
            // Output stylesheet
            echo <<<HTML
<style type="text/css">
{$form_elements} {
\tdisplay: none;
}
{$message_elements} {
\tdisplay: block;
}
</style>

HTML;
        }
    }
}