/** Rewrite date restrictions if the query is day- or category- specific. */
function ec3_filter_posts_where($where)
{
    global $ec3, $wpdb;
    if ($ec3->query->is_page || $ec3->query->is_single || $ec3->query->is_admin) {
        return $where;
    }
    $listing = ec3_get_listing();
    if ($listing == 'D') {
        // disable event calendar's query filtering.
        return $where;
    } elseif ($listing == 'P') {
        // posts-only
        // Hide all events (same as last branch)
        $where .= " AND ec3_sch.post_id IS NULL ";
        $ec3->join_ec3_sch = true;
    } elseif ($ec3->query->is_date) {
        // Transfer events' 'post_date' restrictions to 'start'
        $df = 'YEAR|MONTH|DAYOFMONTH|HOUR|MINUTE|SECOND|WEEK';
        // date fields
        $re = "/ AND (({$df})\\({$wpdb->posts}\\.post_date(,[^\\)]+)?\\) *= *('[^']+'|\\d+\\b))/i";
        if (preg_match_all($re, $where, $matches)) {
            $where_post_date = implode(' AND ', $matches[1]);
            // rdate/rtime should be between start..end:
            $year_num = intval(date('Y'));
            $sdateobj = new ec3_Date($year_num, 1, 1);
            $edateobj = new ec3_Date($year_num, 12, 0);
            $stime = array('00', '00', '00');
            $etime = array('23', '59', '59');
            for ($i = 0; $i < count($matches[1]); $i++) {
                $num = intval(str_replace("'", '', $matches[4][$i]));
                if ('YEAR' == $matches[2][$i]) {
                    $sdateobj->year_num = $edateobj->year_num = $num;
                } elseif ('MONTH' == $matches[2][$i]) {
                    $sdateobj->month_num = $edateobj->month_num = $num;
                } elseif ('DAYOFMONTH' == $matches[2][$i]) {
                    $sdateobj->day_num = $edateobj->day_num = $num;
                } elseif ('HOUR' == $matches[2][$i]) {
                    $stime[0] = $etime[0] = zeroise($num, 2);
                } elseif ('MINUTE' == $matches[2][$i]) {
                    $stime[1] = $etime[1] = zeroise($num, 2);
                } elseif ('SECOND' == $matches[2][$i]) {
                    $stime[2] = $etime[2] = zeroise($num, 2);
                }
            }
            // If the end day num has not been set, then choose the month's last day.
            if ($edateobj->day_num < 1) {
                $edateobj->day_num = 1;
                $edateobj->day_num = $edateobj->days_in_month();
            }
            $where_start = sprintf("start<='%1\$s' AND end>='%2\$s'", $edateobj->to_mysqldate() . ' ' . implode(':', $etime), $sdateobj->to_mysqldate() . ' ' . implode(':', $stime));
            $where = preg_replace($re, '', $where);
            if ($listing == 'E') {
                // EVENTS only
                $where .= " AND ({$where_start}) ";
            } else {
                // ALL
                $is_post = 'ec3_sch.post_id IS NULL';
                $where .= " AND (({$where_post_date} AND {$is_post}) OR " . "({$where_start} AND NOT {$is_post})) ";
            }
            $ec3->order_by_start = true;
            $ec3->join_ec3_sch = true;
        }
        $ec3->order_by_start = true;
        $ec3->join_ec3_sch = true;
    } elseif ($ec3->is_date_range) {
        $w = array();
        if (!empty($ec3->range_from)) {
            $w[] = '%2$s' . ">='{$ec3->range_from}'";
        }
        if (!empty($ec3->range_before)) {
            $w[] = '%1$s' . "<='{$ec3->range_before}'";
        }
        if (!empty($w)) {
            $ws = implode(' AND ', $w);
            $where_start = sprintf($ws, 'ec3_sch.start', 'ec3_sch.end');
            if ($listing == 'E') {
                // EVENTS only
                $where .= " AND ({$where_start}) ";
            } else {
                // ALL
                $pd = "{$wpdb->posts}.post_date";
                $where_post_date = sprintf($ws, $pd, $pd);
                $is_post = 'ec3_sch.post_id IS NULL';
                $where .= " AND (({$where_post_date} AND {$is_post}) OR " . "({$where_start} AND NOT {$is_post})) ";
            }
            $ec3->order_by_start = true;
            $ec3->join_ec3_sch = true;
        }
    } elseif ($ec3->advanced) {
        if ($listing == 'E') {
            // EVENTS only
            // Hide inactive events
            $where .= " AND ec3_sch.post_id IS NOT NULL ";
            $ec3->join_ec3_sch = true;
            $ec3->join_only_active_events = true;
            $ec3->order_by_start = true;
            global $wp;
            $wp->did_permalink = false;
            // Allows zero results without -> 404
        } elseif ($ec3->query->is_search) {
            $where .= ' AND (ec3_sch.post_id IS NULL OR ' . "ec3_sch.end>='{$ec3->today}')";
            $ec3->join_ec3_sch = true;
        } else {
            // Hide all events
            $where .= " AND ec3_sch.post_id IS NULL ";
            $ec3->join_ec3_sch = true;
        }
    }
    return $where;
}