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

时间:2016-06-22 23:05:54

标签: php google-api google-calendar-api google-api-php-client service-accounts

我需要在网页上添加Google日历中的事件列表。 我需要的列表可以在Google日历本身中看到,它是事件列表(议程样式),其中包含来自不同颜色的多个日历的内容。 Google日历也允许在iframe中使用此列表,但问题是,要查看这些列表,用户必须登录,或者我需要公开日历,我无法做到。

曾经有一个日历的私人网址,但现在只有一个iCal供稿可以私下使用。

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

要做到这一点有点过头了,但也许有人之前做过类似的事情,看到它在其他地方完成了吗? 或者能够将它从袖子里甩出来? 或者有更好的建议?

我做的另一个尝试是使用phantomjs登录日历并制作屏幕截图,但我无法在我的网络服务器上运行。

2 个答案:

答案 0 :(得分:1)

我设法使用以下代码模仿议程视图。

对我来说有一些问题,即第二天全天活动的结束日期,以及返回dateTime的非全日活动与仅全日的日期。

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

<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>

答案 1 :(得分:0)

这里有一些代码会显示一个事件,如果GET电话号码位于5个不同电话号码格式之一的Google事件字段中的某个位置,则您需要一个共享日历的服务帐户使用和创建服务帐户时获得的My 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})$/', '\1-\2-\3', $phone);
$display1 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '(\1) \2-\3', $phone);
$display2 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '\1\2\3', $phone);
$display3 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '\1 \2 \3', $phone);
$display4 = preg_replace('/^(\d{3})(\d{3})(\d{4})$/', '(\1)\2-\3', $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)
?>