Тема: Календарь только для выбранных категорий

Постановка задачи.

Часто встречается необходимость выводить календарь cn_calendar() только для одной или для нескольких выбранных категорий.

Такая необходимость может возникнуть, например, когда разработчик не хочет показывать некоторые категории всем пользователям. Или когда на одном "движке" работают несколько "подсайтов" уровня: ввв.домен.ру/сайт1, ввв.домен.ру/сайт2, ввв.домен.ру/сайт3... или сайт1.домен.ру, сайт2.домен.ру, сайт3.домен.ру..., или в других случаях.

Во всех подобных ситуациях очень просто сделать так, чтобы на нужных страницах были видны архивы или новости только нужных категорий, об этом неоднократно говорилось в форуме. Однако календарь (сволочь) подводит и выдаёт секреты, так как безапелляционно выводит сведения обо всех публикациях в базе данных.

Что делать???

Для этого в Strawberry 1.1.1 в файле plugins/etc.php найдите функцию cn_calendar и полностью замените её на эту:

function cn_calendar($categid = '0'){
global $cache, $year, $month, $day, $PHP_SELF, $sql, $config;

//Если категория не указана
if ($categid == '0')
{$cat_cat = $sql->select(array('table' => 'news', 'where' => array('date < '.(time() + $config['date_adjust'] * 60))));}

//Если указана одна категория
elseif (!strpos($categid,',')) 
{$cat_cat = $sql->select(array('table' => 'news', 'where' => array('category ? ['.$categid.']' , 'and', 'date < '.(time() + $config['date_adjust'] * 60))));}

//Если указано несколько категорий
else {
$line = explode(',',$categid);
$cat_cat = $sql->select(array('table' => 'news', 'where' => array('category ? ['.$line[0].']' , 'and', 'date < '.(time() + $config['date_adjust'] * 60))));
    for ($i=1; $i<count($line); $i++) {
    array_push($cat_cat, $sql->select(array('table' => 'news', 'where' => array('category ? ['.$line[$i].']' , 'and', 'date < '.(time() + $config['date_adjust'] * 60)))));
    }

}
    if (!$post_arr = $cache->get('calendar')){
        foreach ($cat_cat as $row){
            $save[] = $row['date'];
        }

        @rsort($save);
        $post_arr = $cache->put(@join("\r\n", $save));
    }

    $post_arr = explode("\r\n", $post_arr);

    $year  = ($year ? $year : $_GET['year']);
    $month = ($month ? $month : $_GET['month']);
    $day   = ($day ? $day : $_GET['day']);

    if ($year and $month){
        $this['month'] = $month;
        $this['year']  = $year;
    } else {
        $this['month'] = date('m', $post_arr[0]);
        $this['year']  = date('Y', $post_arr[0]);
    }

    if (!$calendar = $cache->get(($day ? $day.'.' : '').$this['month'].'.'.$this['year'])){
        foreach ($post_arr as $date){
            if ($this['year'] == date('Y', $date) and $this['month'] == date('m', $date)){
                $events[date('j', $date)] = $date;
            }

            if ($this['month'].$this['year'] != date('mY', $date)){
                $prev_next[] = $date;
            }
        }

        $calendar = $cache->put(calendar($this['month'], $this['year'], $events, $prev_next, $categid));
    }

return $calendar;
}


Далее, в этом же файле ищем функцию calendar и заменяем её на эту:

function calendar($cal_month, $cal_year, $events, $prev_next, $categid){
global $year, $month, $day, $PHP_SELF;

    $first_of_month  = mktime(0, 0, 0, $cal_month, 7, $cal_year);
    $maxdays         = date('t', $first_of_month) + 1; // 28-31
    $cal_day         = 1;
    $weekday         = date('w', $first_of_month); // 0-6

    if (is_array($prev_next)){
        sort($prev_next);

        foreach ($prev_next as $key => $value){
            if ($value < $first_of_month){
                $prev_of_month = $prev_next[$key];
            }
        }

        rsort($prev_next);

        foreach ($prev_next as $key => $value){
            if ($value > $first_of_month){
                $next_of_month = $prev_next[$key];
            }
        }
    }

    if ($prev_of_month){
        $tomonth['prev'] = '<a href="'.cute_get_link(array('date' => $prev_of_month), 'month').($categid != '0' ? '&category='.$categid : '').'" title="'._etc_lang(date('n', $prev_of_month), 'month').date(' Y', $prev_of_month).'">&laquo;</a> ';
    }

    if ($next_of_month){
        $tomonth['next'] = ' <a href="'.cute_get_link(array('date' => $next_of_month), 'month').($categid != '0' ? '&category='.$categid : '').'" title="'._etc_lang(date('n', $next_of_month), 'month').date(' Y', $next_of_month).'">&raquo;</a>';
    }

    $buffer = '<table id="calendar" width="100%" cellpadding="2" cellspacing="0" border="0">
    <tr>
     <td colspan="7" class="menu"><span style="text-transform: uppercase"><b>'.$tomonth['prev'].'<a href="'.cute_get_link(array('date' => $first_of_month), 'month').($categid != '0' ? '&category='.$categid : '').'" title="'._etc_lang(date('n', $first_of_month), 'month').date(' Y', $first_of_month).'">'._etc_lang(date('n', $first_of_month), 'month').' '.$cal_year.$tomonth['next'].'</a></b></span>
    <tr>
     <th class="weekday" style="border-bottom: 1px solid #909090">'._etc_lang(1, 'weekday').'
     <th class="weekday" style="border-bottom: 1px solid #909090">'._etc_lang(2, 'weekday').'
     <th class="weekday" style="border-bottom: 1px solid #909090">'._etc_lang(3, 'weekday').'
     <th class="weekday" style="border-bottom: 1px solid #909090">'._etc_lang(4, 'weekday').'
     <th class="weekday" style="border-bottom: 1px solid #909090">'._etc_lang(5, 'weekday').'
     <th class="weekend" style="border-bottom: 1px solid #909090">'._etc_lang(6, 'weekday').'
     <th class="weekend" style="border-bottom: 1px solid #909090">'._etc_lang(7, 'weekday').'
    <tr>';

    if ($weekday > 0){
        $buffer .= '<td colspan="'.$weekday.'">&nbsp;';
    }

    while ($maxdays > $cal_day){
        if ($weekday == 7){
            $buffer .= '<tr>';
            $weekday = 0;
        }

        # В данный день есть новость
        if ($events[$cal_day]){
            $date['title'] = langdate('l, d M Y', $events[$cal_day]);
            $link = cute_get_link(array('date' => $events[$cal_day]), 'day').($categid != '0' ? '&category='.$categid : '');

            if ($weekday == '5' or $weekday == '6'){ // Если суббота и воскресенье. Слава КПСС!!!
                if ($day == $cal_day){
                    $buffer .= '<td class="weekend"><a href="'.$link.'" title="'.$date['title'].'"><b>'.$cal_day.'</b></a>';
                   } else {
                       $buffer .= '<td class="endday"><a href="'.$link.'" title="'.$date['title'].'">'.$cal_day.'</a>';
                   }
            } else { // Рабочии дни. Вперёд, стахановцы!!!
                if ($day == $cal_day){ // активный
                    $buffer .= '<td class="weekday"><a href="'.$link.'" title="'.$date['title'].'"><b>'.$cal_day.'</b></a>';
                } else {  // пассивный, дурашка
                    $buffer .= '<td class="day"><a href="'.$link.'" title="'.$date['title'].'">'.$cal_day.'</a>';
                }
            }
        } else { // В данный день новостей нет. Хуйовый день...
            if ($weekday == '5' or $weekday == '6'){ // дни, когда по телеку нихуя нет :(
                $buffer .= '<td class="endday">'.$cal_day;
            } else { // работяги хлещат водку после труда
                $buffer .= '<td class="day">'.$cal_day;
            }
        }

        $cal_day++;
        $weekday++;
    }

    if ($weekday != 7){
        $buffer .= '<td colspan="'.(7 - $weekday).'">&nbsp;';
    }

return $buffer.'</table>';
}

Всё! Теперь:

- если функция cn_calendar будет вызываться по-старому:

echo cn_calendar();

то выведется календарь для всех категорий ("стандартный" вид).

- если так:

echo cn_calendar('18');

то выведется календарь только для категории 18.

- если так:

echo cn_calendar('18,19,20');

то выведется календарь только для категорий 18, 19 и 20.

2

Re: Календарь только для выбранных категорий

Заменил функции. Если не указывать категории, т.е. по старому работает, и если указать одну категорию то работает. А вот если указать хотя бы две, или больше выдает такие пары ошибок

Warning: date() expects parameter 2 to be long, string given in /srv/web/.../news/plugins/etc.php on line 82

и

Warning: date() expects parameter 2 to be long, string given in /srv/web/.../news/plugins/etc.php on line 86

Это строчки из цикла

foreach ($post_arr as $date){
            if ($this['year'] == date('Y', $date) and $this['month'] == date('m', $date)){ // это 82 строчка
                $events[date('j', $date)] = $date;
            }

            if ($this['month'].$this['year'] != date('mY', $date)){ // а это 86 строчка
                $prev_next[] = $date;
            }
}

Отредактировано Никола (26 Nov 2009 15:05:08)

Есле кних четать ни будиш - скора грамату забудиш!

3

Re: Календарь только для выбранных категорий

Никто не подскажет почему на строку

 if ($events[$cal_day]){

денвер "ругается" ?

Re: Календарь только для выбранных категорий

а что перед этой строкой?

Здесь молодость бродит крылато, и старость не клонит голов...
Демо площадка Strawberry 1.2 - заходим и тестируем!

Re: Календарь только для выбранных категорий

Никола пишет:

Заменил функции. Если не указывать категории, т.е. по старому работает, и если указать одну категорию то работает. А вот если указать хотя бы две, или больше выдает такие пары ошибок

Warning: date() expects parameter 2 to be long, string given in /srv/web/.../news/plugins/etc.php on line 82

и

Warning: date() expects parameter 2 to be long, string given in /srv/web/.../news/plugins/etc.php on line 86

Это строчки из цикла

foreach ($post_arr as $date){
            if ($this['year'] == date('Y', $date) and $this['month'] == date('m', $date)){ // это 82 строчка
                $events[date('j', $date)] = $date;
            }

            if ($this['month'].$this['year'] != date('mY', $date)){ // а это 86 строчка
                $prev_next[] = $date;
            }
}

Таже проблема, кто нибудь разобрался с этим вопросом?

Мученики только вредили истине.