Как разобрать повторяющиеся события с Zend GData? - PullRequest
1 голос
/ 28 мая 2011

Существует множество учебных пособий о том, как запрашивать и анализировать список событий из Календаря Google с помощью Zend GData.

Но все учебные пособия предполагают, что события никогда не повторяются.(В некотором смысле, они описывают, как настроить повторяющиеся события, но не как их анализировать / отображать.)

Поэтому я написал скрипт для копирования событий из Календаря Google на веб-сайт, но он просто не 'не работает, потому что некоторые события в календаре повторяются, а метод, описанный в руководствах, приводит к довольно случайному выводу.

Есть идеи?

1 Ответ

4 голосов
/ 22 ноября 2011

Я думаю, что наконец нашел ответ, который вы действительно ищете. Для http://code.google.com/apis/calendar/data/1.0/reference.html#Parameters, необходимо установить для параметра 'singleevents' значение 'true', заставляя возвращаемые данные выполнять собственный анализ и упорядочение повторяющихся событий. Таким образом, ваш код (на основе http://code.google.com/apis/calendar/data/1.0/developers_guide_php.html#RetrievingDateRange) будет выглядеть примерно так:

function outputCalendarByDateRange($client, $startDate='2007-05-01', $endDate='2007-08-01') {
  $gdataCal = new Zend_Gdata_Calendar($client);
  $query = $gdataCal->newEventQuery();
  $query->setUser('default');
  $query->setVisibility('private');
  $query->setProjection('full');
  $query->setOrderby('starttime');
  $query->setStartMin($startDate);
  $query->setStartMax($endDate);

  $query->setsingleevents('true');

  $eventFeed = $gdataCal->getCalendarEventFeed($query);
  echo "<ul>\n";
  foreach ($eventFeed as $event) {
    echo "\t<li>" . $event->title->text .  " (" . $event->id->text . ")\n";
    echo "\t\t<ul>\n";
    foreach ($event->when as $when) {
      echo "\t\t\t<li>Starts: " . $when->startTime . "</li>\n";
    }
    echo "\t\t</ul>\n";
    echo "\t</li>\n";
  }
  echo "</ul>\n";
}

Данные, возвращаемые из этой функции, имеют одно событие для каждого экземпляра повторяющихся событий, упорядоченное правильно среди всех остальных «обычных» событий. Исключения из правил повторения (например, отмена одного события) также корректно отражены.

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

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

echo "\t\t\t<li>Starts: " . $event->when->startTime . "</li>\n";

Но так как пример Google включает в себя этот второй цикл foreach, вероятно, безопаснее оставить его внутри.

Надеюсь, вам еще не поздно помочь!

----- Оригинальный ответ: -----

(включено только для полноты и потому, что я до сих пор использую этот базовый метод для объединения событий из нескольких календарей)

Я сейчас работаю над этим сам, использую PHP для анализа канала и отображения некоторых настроенных XML-данных на основе данных. Единственное решение, которое я нашел, - это получить даты / время всех событий, повторяющихся или нет, используя:

$eventFeed = $gdataCal->getCalendarEventFeed($query);
foreach ($eventFeed as $event) {
    foreach ($event->when as $when) {
        $start=strtotime($when->startTime);
        $end=strtotime($when->endTime);
    }
}

Который работает довольно хорошо. Проблема в том, что все события будут возвращаться «сгруппированными» в порядке очередных вхождений. То есть прямо сейчас понедельник. Если у вас есть повторяющееся событие каждый вторник и другое повторяющееся событие каждый четверг, и вы запрашиваете его для всех событий в течение следующих 90 дней, список, который вы получите, будет сначала перечислять каждый экземпляр события вторника в течение следующих 90 дней. , а затем он будет продолжать перечислять каждый случай события четверга. Для моих целей (и это звучит так же, как и для вас) я хотел, чтобы список был в порядке появления отдельных событий.

Единственный способ, который я нашел, это вставить данные из каждого отдельного экземпляра во временную таблицу базы данных SQL, включая столбец, указывающий метку времени начала события. Затем, когда все это заносится в базу данных, я могу попросить вернуть мне события, упорядоченные по метке времени.

Таким образом, мой цикл стал чем-то вроде:

mysql_query("CREATE TEMPORARY TABLE `temp` (`title` TEXT NOT NULL,`date` TEXT NOT NULL,`timestamp` TIMESTAMP NOT NULL)");
$eventFeed = $gdataCal->getCalendarEventFeed($query);
foreach ($eventFeed as $event) {
    foreach ($event->when as $when) {
        $start=strtotime($when->startTime);
        $end=strtotime($when->endTime);
    mysql_query("INSERT INTO `temp` (`title`,`date`,`timestamp`) VALUES ('".$event->title->text."','".date("M d h:i a",$start)."-".date("h:i",$end)."','".date("Y-m-d H:i:s",$start)."')");
    }
}
$result=mysql_query("SELECT * FROM `mobile_app_events` ORDER BY `timestamp` ASC");
while($row=mysql_fetch_assoc($result)) {
    echo "<item>\n";
    echo "<title>".$row['title']."</title>\n";
    echo "<date>".$row['date']."</date>\n";
    echo "</item>\n";
}

Теперь, я предупреждаю вас - причина, по которой я нашел эту тему, в том, что я сам ищу ответ ... кажется, что если повторяющиеся события имеют какие-либо исключения (например, событие следующего четверга отменено), что не отражается в выводе с использованием этих кодов. Несмотря на то, что событие следующего четверга удалено из представления Календаря Google, оно все равно отображается на этой странице.

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

...