Повторяющиеся узлы, возвращенные из SQL-запроса модуля


Я затрудняюсь настроить модуль блока календаря под свои нужды. Я написал пользовательский модуль, который запрашивает в моей базе данных опубликованные узлы, содержащие определенный термин таксономии. Это работает по желанию; 3 объекта узла возвращаются в виде массива. Однако этот массив возвращается в общей сложности 35 раз. Когда я выполняю запрос в своем диспетчере SQL, 3 строки возвращаются без повторения. Есть ли что-то вопиюще неправильное в моем коде, что я не смог обнаружить?

/*
*
* Implementation of hook_calendar_block
*
*/

function calendar_block_mod_calendar_block(&$calendar, &$date, $op) {
  switch($op) {

   case 'alter':
                $sql = "SELECT DISTINCT node.nid AS nid 
                                FROM {node}
                                INNER JOIN term_node term_node ON node.vid = term_node.vid 
                                WHERE (node.status <> 0) AND (term_node.tid = 5)"; 

                $results = db_query($sql);

        while ($node = db_fetch_object($results))
        {    
          $events[] = node_load(array('nid' => $node->nid));
        }

        foreach ($events as $var){
                $thisPath = $var->path;
                                $nodeTitle = $var->title;
                $thisDate = substr($var->field_event_date[0]['value'],0,10);
                                $realDay = substr($thisDate, 8,2);
                $realDate = substr($thisDate, 5, 2) . "-" . ( $realDay < 10 ? substr($realDay, 1,1) : $realDay ) ."-". substr($thisDate, 0, 4);

                                //$dayInfo[] = array ('date' => $realDate, 'title' => $nodeTitle,  'path' => $thisPath );

                                if ($date->date == $realDate) {

                                    $date->content = '<span class="tooltip">'. l($date->day, $thisPath) .'</span>';
                                    $date->content .= '<div class="tooltip_hidden">'. l($nodeTitle, $thisPath) .'</div>';

                                }
                            }
          break;

        case 'load':

        // Change the weekday's format and set the first day of the week to sunday.
        $calendar->weekdays =  array(
            'su' => 'S',
            'mo' => 'M',
            'tu' => 'T',
            'we' => 'W',
            'th' => 'T',
            'fr' => 'F',
            'sa' => 'S',
        );

        break;
  }

}

Отредактировано, чтобы включить весь код из моего модуля - Во всяком случае, я надеюсь, что это может дать другим аналогичную отправную точку. если код выглядит как беспорядок, то это потому, что это мой первый модуль.

Код работает: узлы с требуемым термином таксономии извлекаются из базы данных, и каждая дата в календаре становится ссылкой на соответствующий узел. Однако при ближайшем рассмотрении 3 строки возвращаются 35 раз, так что делайте что-нибудь помимо этого (например, выбор узлов, если есть несколько на одну дату) становится проблемой/невозможной.

 3
Author: kiamlaluno, 2011-05-10

1 answers

Я только что бросил быстрый взгляд на модуль calendar_block. Из того, что я могу сказать, hook_calendar_block op alter вызывается для каждого отдельного дня в календаре. Я думаю, это имеет смысл, поскольку позволяет изменять внешний вид в любой день.

Я предполагаю, что в календаре на вашем сайте 35 дней, поэтому ваш запрос выполняется 35 раз.

Вы можете использовать переменную static, чтобы выполнять свои действия только один раз или сохранять запрос и т. Д.

Что-то вроде этого может сработать:

function calendar_block_mod_calendar_block(&$calendar, &$date, $op) {
  switch($op) {
    case 'alter':
      static $events;
      if (empty($events)) {
        $sql = "SELECT DISTINCT node.nid AS nid 
              FROM {node}
              INNER JOIN term_node term_node ON node.vid = term_node.vid 
              WHERE (node.status <> 0) AND (term_node.tid = 5)"; 

        $results = db_query($sql);

        while ($node = db_fetch_object($results)) {    
          $events[] = node_load(array('nid' => $node->nid));
        }
      }
      ....
  }
}

В приведенный выше код не отражает случай, когда результата нет, и предназначен только для подтверждения концепции.

Обновление:
Если вы хотите запустить весь код только один раз, вы можете сделать что-то вроде этого:

function calendar_block_mod_calendar_block(&$calendar, &$date, $op) {
  switch($op) {
    case 'alter':
      static $code_executed;
      if (!$code_executed) {
        ...
        $code_executed = TRUE;
      }
  }
}
 2
Author: googletorp, 2011-05-11 17:29:23