如何使用 PHP 创建 Google 日历的列表视图

How to create a list view of Google Calendar with PHP

我需要将 Google 日历中的事件列表放在网页上。 我需要的列表可以在 Google 日历本身中看到,它是事件列表(议程样式),内容来自多个不同颜色的日历。 Google 日历也允许在 iframe 中包含此列表,但问题是,要查看这些列表,用户必须登录,否则我需要制作日历 public,但我做不到做。

以前有私人日历 url,但现在只有 iCal 提要私人可用。

所以我试图找到一个 PHP 脚本来创建这样一个列表。 令人惊讶的是,我没有找到太多。 大多数页面依赖于 public 日历,或者只是关于如何连接的非常基本的示例,例如 Google 的 php 示例 https://developers.google.com/google-apps/calendar/quickstart/php#step_3_set_up_the_sample 我设法开始工作,但这与我需要的相去甚远。 我需要一些可以格式化的 html 输出,以及来自 3 个不同日历的数据。

要做到这一点让我有点头疼,但也许有人以前做过类似的事情,在其他地方见过吗? 或者能够摆脱他们的袖子? 或者有更好的建议?

我做的另一个尝试是使用 phantomjs 登录日历并截屏,但我不能 运行 在我的网络服务器上。

我设法用下面的代码模仿了议程视图。

我遇到了一些问题,即全天活动的结束日期是第二天,非全天活动返回日期时间与全天的唯一日期。

我认为代码过于复杂,这是我在缓慢的迭代步骤中找到解决方案...

<html>
  <head>
    <style type="text/css">
      html {
        font-family: sans-serif;
      }
      .trips {
        color:red;
      }
      .courses {
        color:blue;
      }
      .canceled {
        color:orange;
        text-decoration:line-through;
      }
      .marketing {
        color:green;
      }
      tr>td {
        vertical-align: top;
      }
      td.time {
        width: 110px;
      }
      td.date {
        width: 140px;
      }
      td.summary {
        font-weight:bold;
      }
      td {
        padding: 0 0 5px 0;
        border-bottom: 2px solid grey;
      }
      td td {
        border-bottom: none;
      }
      span.location {
        font-weight:normal;
        color:black;
        margin-left:10px;
      }
    </style>
  </head>
  <body>
    [html comment broken up, to keep syntax highlighting in the php below]
    < ! -- // having a html comment around php keeps php debug output from echo, print_r etc in source view
<?php
  /******************
  * list calendar-events mimicking the google calendar agenda-view
  * allows to show a non-public calendars to non-authenticated clients
  * code fragments from
  * http://www.daimto.com/google-calendar-api-with-php-service-account/
  * https://developers.google.com/google-apps/calendar/v3/reference/events/list#response
  * https://developers.google.com/google-apps/calendar/quickstart/php#step_3_set_up_the_sample
  ******************/
  require_once 'google-api-php-client/src/Google/autoload.php';
  session_start();
  $Email_address = 'k....e@b....3.iam.gserviceaccount.com';
  // for security reasons, keep key_file outside webroot:
  $key_file_location = '/home/t...../...41.p12';
  $client = new Google_Client();
  $client-> setApplicationName("K....");
  $key = file_get_contents($key_file_location);
  // the calendars to query
  $calendars = array(
    'trips'    => 'k....st@group.calendar.google.com',
    'courses'  => '3....4s@group.calendar.google.com',
    'canceled' => 'p....f@group.calendar.google.com',
  );
  $agenda = array(); // the merged result from all calendarsi
  $maxResults = 15; // no. of results to get (per calendar)
  $firstDate = new DateTime(); // the date from which on we want the agenda
  $firstDate->setTime(0,0,0); // date "without" time, we think in full days only
  // $firstDate->modify('+2 days'); // testing other start-dates
  setlocale (LC_ALL, 'de_DE'); // to get weekdays & monthnames correct
  $scopes ="https://www.googleapis.com/auth/calendar.readonly";
  $cred = new Google_Auth_AssertionCredentials(
    $Email_address,
    array($scopes),
    $key
  );
  $client->setAssertionCredentials($cred);
  if($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion($cred);
  }
  $service = new Google_Service_Calendar($client);

  foreach($calendars as $cal_name => $cal_id) {
    // get the dates from each calendar
    $calendar_res = $service->calendars->get($cal_id);
    $optParams = array(
      'maxResults' => $maxResults,
      'orderBy' => 'startTime',
      'singleEvents' => true,
      'timeMin' => $firstDate->format('c')
    );
    $events = $service->events->listEvents($calendar_res->id, $optParams);

    foreach ($events->getItems() as $event) {
      $startDate = new DateTime();
      $endDate = new DateTime();
      // full-day events use 'date', others 'dateTime' so we need to treat separately:
      if(isset($event->start->date)){
        // it's a full day event, only a date is given
        $startDate->setTimestamp(strtotime($event->start->date));
        $endDate->setTimestamp(strtotime($event->end->date));
        // full-day end-date is returned by google as the next day (midnight),
        // correct this for our display:
        $endDate->sub(new DateInterval('P1D'));
        // remove times, they would contain data from the last processed non- full-day event
        // also, we will test ifset to recognize full- against non- full-day events
        unset($startTime);
        unset($endTime);
      }else{
        // it's a non-full day, having start/end dates AND times
        $startDate->setTimestamp(strtotime($event->start->dateTime));
        $endDate->setTimestamp(strtotime($event->end->dateTime));
        // extract times
        $startTime = $startDate->format('G:i');
        $endTime = $endDate->format('G:i');
        // set times to zero, so date comparison works correctly
        $startDate->setTime(0,0,0);
        $endDate->setTime(0,0,0);
      }

      // for every day of the event, make an entry in the agenda
      $currDate = $startDate; // the date we are about to add an entry to
      while ($endDate >= $currDate){
        // don't add entries that are before our first wanted date
        if ($currDate >= $firstDate){
          if (isset ($startTime)){
            $time = $startTime . " - " . $endTime;
          }else{
            $time = "Ganztägig";
          };
          // we save the date in a way so the agenda-array can later be sorted by it
          $agenda[$currDate->format('Y-m-d')][] =
            array(
              'cal' => $cal_name,
              'summary' => $event->getSummary(),
              'location' => $event->getLocation(),
              'start' => $startDate->format('Y-m-d') . " - " . $startTime,
              'end' => $endDate->format('Y-m-d') . " - " . $endTime,
              'time' => $time
            );
        };
        // go to next day
        $currDate->modify('+1 day');
      };
    }
  }

  // the agenda-array is not yet sorted, events were added by calendar by date, not just by date
  ksort ($agenda); // sort by key (date)
  //var_dump($agenda);
  //print_r($agenda);
?>
    // end of html comment around php (keeps debug output in source view) -->

<?
  //output
  echo "    <table>";
  foreach ($agenda as $aDate => $events){
    // a row for every date
    echo "\n      <tr>";
    echo "\n        <td class=\"date\">" . strftime('%a %e. %B', strtotime($aDate)) . "</td>";
    echo "\n        <td>";
    // a table of events for every day
    echo "\n          <table >";
    foreach ($events as $aEvent){
      // a row for every event
      echo "\n            <tr>";
      echo "\n              <td class=\"time\">" . $aEvent['time'] ."</td>";
      echo "\n              <td class=\"" . $aEvent['cal'] . " summary\">" . $aEvent['summary'];
      echo "\n                <span class=\"location\">" . $aEvent['location'] . "</span>";
      echo "\n              </td>";
      echo "\n            </tr>";
     };
    echo "\n          </table>";
    echo "\n        </td>";
    echo "\n      </tr>";
  };
  echo "\n    <table>\n";
?>
  </body>
</html>

这里有一些代码,如果 GET phone 号码位于 google 事件字段中的某处,有 5 种不同的 phone 数字格式之一,您将需要与日历共享的服务帐户以及创建服务帐户时获得的我的 Project.json 文件需要放入服务器上的工作文件夹(与 .

相同的文件夹)
<?php

//error_reporting(E_ALL);
//ini_set("display_errors", 1);

require_once __DIR__.'/vendor/autoload.php'; 

$client = new Google_Client();
$credentialJson= __DIR__ . '/My Project-somehexidecimal.json'; //name of your My Project .json file
$calendarId='youremail'; //your google calendar id
$phone= $_GET['phone'];

$display = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '--', $phone);
$display1 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '() -', $phone);
$display2 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '', $phone);
$display3 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '  ', $phone);
$display4 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '()-', $phone);

$client->setAuthConfig($credentialJson);
$client->addScope('https://www.googleapis.com/auth/calendar');

$service = new Google_Service_Calendar($client);

$params = array(
'q' => $display,
'singleEvents' => true,
//'orderBy' => 'startTime',
'timeMin' => date(DateTime::ATOM),
'maxResults' => 1
);
$params1 = array(
'q' => $display1,
'singleEvents' => true,
//'orderBy' => 'startTime',
'timeMin' => date(DateTime::ATOM),
'maxResults' => 1 
);
$params2 = array(
'q' => $display2,
'singleEvents' => true,
//'orderBy' => 'startTime',
'timeMin' => date(DateTime::ATOM),
'maxResults' => 1 
);
$params3 = array(
'q' => $display3,
'singleEvents' => true,
//'orderBy' => 'startTime',
'timeMin' => date(DateTime::ATOM),
'maxResults' => 1
);
$params4 = array(
'q' => $display4,
'singleEvents' => true,
//'orderBy' => 'startTime',
'timeMin' => date(DateTime::ATOM),
'maxResults' => 1
);

$events = $service->events->listEvents($calendarId, $params);

if (count($events->getItems()) == 0) {
$events = $service->events->listEvents($calendarId, $params1);
}
if (count($events->getItems()) == 0) {
$events = $service->events->listEvents($calendarId, $params2);
}
if (count($events->getItems()) == 0) {
$events = $service->events->listEvents($calendarId, $params3);
}
if (count($events->getItems()) == 0) {
$events = $service->events->listEvents($calendarId, $params4);
}
if (count($events->getItems()) == 0) {
print "No upcoming events found.\n";
}
$calTimeZone = $events->timeZone;

date_default_timezone_set($calTimeZone);

foreach ($events->getItems() as $event) {

        $starttime= $event->getstart()['dateTime'];
        $endtime= $event->getend()['dateTime'];
        $description=$event->getDescription();
        $summary=$event->getSummary();
        $eventid = $event->getid();
        $location = $event->getlocation();

     $eventDateStr = $event->start->dateTime;
     if(empty($eventDateStr))
     {
         $eventDateStr = $event->start->date;
     }

     $temp_timezone = $event->start->timeZone;

     if (!empty($temp_timezone)) {
     $timezone = new DateTimeZone($temp_timezone);
 } else { $timezone = new DateTimeZone($calTimeZone);
     }

     $eventdate = new DateTime($eventDateStr,$timezone);
     $link = $event->htmlLink;
             $TZlink = $link . "&ctz=" . $calTimeZone;
     $newmonth = $eventdate->format("M");
     $newday = $eventdate->format("j");
            }


    ?>
    <div class="event-container">
    <div class="eventDate">
    <span class="month"><?php

    echo $newmonth;

     ?></span><br />
    <span class="day"><?php

    echo $newday;

     ?></span><span class="dayTrail"></span>
</div>
<div class="eventBody">
    <a href="<?php echo $TZlink;
?>">

    <?php echo $summary, '<br>', $location, '<br>', $description;
    ?>
    </a>
</div>
</div>
 <?php

 $notes= html_entity_decode ($description)
?>