如何使用 Zend GData 解析重复事件?

发布于 2024-11-10 15:13:27 字数 223 浏览 0 评论 0原文

有很多关于如何使用 Zend GData 从 Google Calendar 请求和解析事件列表的教程。

但所有教程都假设事件永远不会重复。 (某种程度上,他们描述了如何设置重复事件,但没有描述如何解析/显示它们。)

因此,我编写了一个脚本来将事件从 Google 日历复制到网站,但它不起作用,因为某些日历中的事件正在重复,并且教程中描述的方法会产生相当随机的输出。

有什么想法吗?

there are plenty of tutorials on how to request and parse a list of events from Google Calendar using Zend GData.

But all tutorials assume that events never repeat. (Kind of, they describe how to set up repeating events, but not how to parse / display them.)

So I wrote a script to copy events from Google Calendar to a web site, but it just doesn't work because some of the events in the calendar are repeating and the method described in the tutorials results in pretty random output.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别低头,皇冠会掉 2024-11-17 15:13:27

我想我终于找到了你真正寻找的答案。根据 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#RetrivingDateRange) 看起来像:

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”循环的情况下完成此操作,因为现在每个事件应该只有一个“when”...将第 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 日历视图中删除,但它仍然显示在此页面上。

除此之外,(假设您可以访问数据库),这似乎可以解决问题。我确实在该过程之前添加了几行来启动事务,理论上它可能会加快数据的渲染速度,而不必提交每个插入。

I think I've finally found the answer you're really looking for. Per http://code.google.com/apis/calendar/data/1.0/reference.html#Parameters, you need to set the 'singleevents' parameter to 'true', forcing the data returned to do it's own parsing and ordering of recurring events. So your code (based on http://code.google.com/apis/calendar/data/1.0/developers_guide_php.html#RetrievingDateRange) will look something like:

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";
}

The data that's returned from this function has a single event for each instance of your repeating events, ordered correctly among all the rest of the "normal" events. Exceptions to the recurrance rules (single event cancellations, for instance) are correctly reflected, as well.

So I think you can now use that method without any caveats or warnings...it should give you the data you want, in the way you want.

You can probably do it without the second "foreach" loop, since each event should only have one "when" now...replace lines 18-20 with

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

But since Google's example does include that second foreach loop, it's probably safer to leave it in.

Hope it's not too late to help you!

-----Original answer:-----

(included just for the sake of completeness and because I'm still using this basic method to combine events from multiple calendars)

I'm working on this right now myself, using PHP to parse the feed and display some customized XML based on the data. The only solution I have come up with is to retrieve the dates/times of all the events, recurring or not, using:

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

Which works pretty well. The issue is that all the events will be returned "grouped" in order of the next occurances. That is, say it's Monday right now. If you've got a repeating event every Tuesday and another repeating event every Thursday, and you ask it for all events in the next 90 days, the list you'll get will first list every instance of the Tuesday event for the next 90 days, and THEN it will go on to list every instance of the Thursday event. For my purposes (and it sounds like, yours too), I wanted the list to be in order of the individual events coming up.

The only way I've found to do it, is to insert the data from each individual instance into a temporary SQL database table, including a column indicating the timestamp of the event's beginning. Then once it's all entered in the database, I can request that it give me back the events, ordered by the timestamp.

Thus my loop became something like:

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";
}

Now, I'll caution you- the reason I've found this topic is because I'm looking for an answer myself...it seems that if the recurring events have any exceptions (for instance, next Thursday's event is cancelled), that doesn't get reflected in the output using these codes. Though next Thursday's event is deleted from your Google Calendar view, it still shows up on this page.

Other than that, (and assuming you've got access to a database), this seems to do the trick. I did add in a few lines to start a transaction before the process, with the theory that it might speed up the rendering of the data, not having to commit every insert.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文