เราได้เคยมีเนื้อหา เกี่ยวกับการดึงข้อมูลจาก google calendar ด้วย php
สามารถทำทวนเนื้อหาได้ที่บทความ
การดึงข้อมูลจาก google calendar ด้วย php เบื้องต้น http://niik.in/763
https://www.ninenik.com/content.php?arti_id=763 via @ninenik
เนื้อหาตอนต่อไปนี้ เรามาเพิ่มความสามารถให้เราทำการเพิ่มข้อมูลผ่านรูปแบบ
ฟอร์มที่กำหนดเอง ส่งค่าไปบันทึกบน google calendar ซึ่งเป็นเนื้อหาต่อเนื่อง
จากตอนที่กล่าวไปแล้วข้างต้น
การอนุญาตใช้งาน Google Calendar
ในการใช้งาน Google Client Library สำหรับเขียนคำสั่ง API เพื่อเรียกใช้ Google calendar API
จากตอนเที่แล้ว เรากำหนด scope เป็น CALENDAR_READONLY ซึ่งเป็นค่าที่ใช้สำหรับอ่านค่า
ได้อย่างเดียว เหมาะใช้งานในกรณีที่เราไม่ได้ต้องการ เพิ่ม ลบ หรือแก้ไข calendar ผ่าน API
ไฟล์ calendar.php บางส่วน ตอนที่แล้ว
1 2 3 | define( 'SCOPES' , implode( ' ' , array ( Google_Service_Calendar::CALENDAR_READONLY) )); |
แต่กรณีนี้ หรือกรณีที่เราต้องการจัดการเพิ่มเติมมากกว่าการดึงข้อมูลมาแสดงอย่างเดียว เราจำเป็น
ต้องกำหนดค่า scope เป็นค่าที่เหมาะสม สามารถเลือกได้ดังนี้
https://developers.google.com/resources/api-libraries/documentation/calendar/v3/php/latest/class-Google_Service_Calendar.html
- CALENDAR สามารถทำทุกอย่างใน calendar ได้
- CALENDAR_EVENTS สามารถแสดงและแก้ไข event ใน calendar ได้
- CALENDAR_EVENTS_READONLY สามารถแสดงข้อมูล event ทั้งหมดใน calendar ได้
- CALENDAR_READONLY สามารถดูข้อมูลของ calendar ได้อย่างเดียว
- CALENDAR_SETTINGS_READONLY สามารถดูการตั้งค่าของ calendar ได้
scope หรือขอบเขตค่าเหล่านี้ เราสามารถนำไปกำหนด เพื่อขอใช้สิทธิการเข้าถึง google calendar ตามความเหมาะสม
สามารถกำหนดได้มากกว่า 1 ค่า ตัวอย่างเช่น เราต้องการ ให้สามารถเพิ่มลบแก้ไข หรือทำทุกอย่างใน calendar ได้
เราก็ให้ทำการปรับค่า scope เป็นประมาณนี้
1 2 3 | define( 'SCOPES' , implode( ' ' , array ( Google_Service_Calendar::CALENDAR) )); |
หรือกรณีต้องการ ดูการตั้งค่าด้วยก็สามารถกำหนดเพิ่มเข้าไปเป็นดังนี้
1 2 3 4 | define( 'SCOPES' , implode( ' ' , array ( Google_Service_Calendar::CALENDAR, Google_Service_Calendar::CALENDAR_SETTINGS_READONLY) )); |
อย่างไรก็ตาม การกำหนด scope ที่จะใช้งาน ก็ต้องไปดู คำสั่ง api ที่เราจะใช้ มีเงื่อนไข scope ที่เราต้องกำหนด
เป็นอย่างไร ตามเอกสารอ้างอิง เช่น กรณีการเพิ่ม event หรือกิจกรรมลงใน calendar
ก็จำเป็นต้องเลือกว่าจะใช้อย่างใด อย่างหนึ่งจาก scope ที่กำหนดนี้
Scope
https://www.googleapis.com/auth/calendar
https://www.googleapis.com/auth/calendar.events
เมื่อเราได้ scope ที่ต้องการแล้ว เราก็ต้องทำการขอสิทธิการเข้าถึงใหม่แทนตัวเดิม โดยให้ทำการลบ
โฟลเดอร์ .credentials ถ้ามีอยู่แล้ว ออกไปก่อน เพื่อสร้างการขอสิทธิใหม่ โดยเริ่มต้นทำการรัน
ไฟล์ calendar.php ผ่าน command line เหมือนเดิม ในขั้นตอนจากบทความแรก http://niik.in/763
ตรงนี้ไม่ขออธิบายซ้ำ ย้อนดูได้ที่ลิ้งค์ที่แนะนำ
ในที่นี้สมมติเราจะจัดการแค่ใน event สำหรับเพิ่ม ลบ แก้ไข event ได้ เราจะใช้ค่า scope เป็น
CALENDAR_EVENTS
ไฟล์ calendar.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | <?php /** Error reporting */ error_reporting (0); ini_set ( 'display_errors' , FALSE); ini_set ( 'display_startup_errors' , FALSE); require_once __DIR__ . '/vendor/autoload.php' ; ?> <!DOCTYPE html> <html> <head> <title>Google Calendar API </title> <meta charset= 'utf-8' /> </head> <body> <p>Google Calendar API </p> <?php define( 'APPLICATION_NAME' , 'CALENDAR-PHP-2021' ); define( 'CREDENTIALS_PATH' , __DIR__ . '/.credentials/calendar.json' ); define( 'CLIENT_SECRET_PATH' , __DIR__ . '/client_secret.json' ); // If modifying these scopes, delete your previously saved credentials // at ~/.credentials/calendar-php-quickstart.json define( 'SCOPES' , implode( ' ' , array ( Google_Service_Calendar::CALENDAR_EVENTS) )); /*if (php_sapi_name() != 'cli') { throw new Exception('This application must be run on the command line.'); }*/ /** * Returns an authorized API client. * @return Google_Client the authorized client object */ function getClient() { $client = new Google_Client(); $client ->setApplicationName(APPLICATION_NAME); $client ->setScopes(SCOPES); $client ->setAuthConfig(CLIENT_SECRET_PATH); $client ->setAccessType( 'offline' ); $guzzleClient = new \GuzzleHttp\Client( array ( 'curl' => array ( CURLOPT_SSL_VERIFYPEER => false, ), )); $client ->setHttpClient( $guzzleClient ); // Load previously authorized credentials from a file. $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH); if ( file_exists ( $credentialsPath )) { $accessToken = json_decode( file_get_contents ( $credentialsPath ), true); } else { // Request authorization from the user. $authUrl = $client ->createAuthUrl(); printf( "Open the following link in your browser:\n%s\n" , $authUrl ); print 'Enter verification code: ' ; $authCode = trim( fgets (STDIN)); // Exchange authorization code for an access token. $accessToken = $client ->fetchAccessTokenWithAuthCode( $authCode ); // Store the credentials to disk. if (! file_exists (dirname( $credentialsPath ))) { mkdir (dirname( $credentialsPath ), 0700, true); } file_put_contents ( $credentialsPath , json_encode( $accessToken )); printf( "Credentials saved to %s\n" , $credentialsPath ); } $client ->setAccessToken( $accessToken ); // Refresh the token if it's expired. if ( $client ->isAccessTokenExpired()) { $client ->fetchAccessTokenWithRefreshToken( $client ->getRefreshToken()); file_put_contents ( $credentialsPath , json_encode( $client ->getAccessToken())); } return $client ; } /** * Expands the home directory alias '~' to the full path. * @param string $path the path to expand. * @return string the expanded path. */ function expandHomeDirectory( $path ) { $homeDirectory = getenv ( 'HOME' ); if ( empty ( $homeDirectory )) { $homeDirectory = getenv ( 'HOMEDRIVE' ) . getenv ( 'HOMEPATH' ); } return str_replace ( '~' , realpath ( $homeDirectory ), $path ); } // Get the API client and construct the service object. $client = getClient(); $service = new Google_Service_Calendar( $client ); // Print the next 10 events on the user's calendar. $calendarId = 'primary' ; $optParams = array ( 'maxResults' => 10, 'orderBy' => 'startTime' , 'singleEvents' => TRUE, 'timeMin' => date ( 'c' ), ); $results = $service ->events->listEvents( $calendarId , $optParams ); if ( count ( $results ->getItems()) == 0) { print "No upcoming events found.\n" ; } else { print "Upcoming events:\n" ; foreach ( $results ->getItems() as $event ) { $start = $event ->start->dateTime; if ( empty ( $start )) { $start = $event ->start-> date ; } printf( "%s (%s)\n" , $event ->getSummary(), $start ); printf( '<br>' ); } } ?> </body> </html> |
ทดสอบรันผ่านบราวเซอร์

เนื่องจากยังไม่มีข้อมูลใดๆ จึงได้ผลลัพธ์ข้างต้น
การเพิ่มข้อมูล Events ไปยัง Google calendar
ตอนนี้เราสามารถเชื่อมต่อ และรับสิทธิการเข้าถึง google calendar ผ่าน Calendar API
เรียบร้อยแล้ว ขั้นตอนต่อไป เราจะมาทดสอบการเพิ่มข้อมูล event เข้าไปใน calendar โดยให้เราสร้าง
ไฟล์ชื่อ add_event.php และใช้รูปแบบโค้ดคล้ายกับ calendar.php แต่ปรับแต่งเล็กน้อย ดังนี้
ไฟล์ add_event.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | <?php /** Error reporting */ error_reporting (0); ini_set ( 'display_errors' , FALSE); ini_set ( 'display_startup_errors' , FALSE); require_once __DIR__ . '/vendor/autoload.php' ; ?> <!DOCTYPE html> <html> <head> <title>Google Calendar API </title> <meta charset= 'utf-8' /> </head> <body> <p>Add new Event</p> <?php define( 'APPLICATION_NAME' , 'CALENDAR-PHP-2021' ); define( 'CREDENTIALS_PATH' , __DIR__ . '/.credentials/calendar.json' ); define( 'CLIENT_SECRET_PATH' , __DIR__ . '/client_secret.json' ); // If modifying these scopes, delete your previously saved credentials // at ~/.credentials/calendar-php-quickstart.json define( 'SCOPES' , implode( ' ' , array ( Google_Service_Calendar::CALENDAR_EVENTS) )); /*if (php_sapi_name() != 'cli') { throw new Exception('This application must be run on the command line.'); }*/ /** * Returns an authorized API client. * @return Google_Client the authorized client object */ function getClient() { $client = new Google_Client(); $client ->setApplicationName(APPLICATION_NAME); $client ->setScopes(SCOPES); $client ->setAuthConfig(CLIENT_SECRET_PATH); $client ->setAccessType( 'offline' ); $guzzleClient = new \GuzzleHttp\Client( array ( 'curl' => array ( CURLOPT_SSL_VERIFYPEER => false, ), )); $client ->setHttpClient( $guzzleClient ); // Load previously authorized credentials from a file. $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH); if ( file_exists ( $credentialsPath )) { $accessToken = json_decode( file_get_contents ( $credentialsPath ), true); } else { // Request authorization from the user. $authUrl = $client ->createAuthUrl(); printf( "Open the following link in your browser:\n%s\n" , $authUrl ); print 'Enter verification code: ' ; $authCode = trim( fgets (STDIN)); // Exchange authorization code for an access token. $accessToken = $client ->fetchAccessTokenWithAuthCode( $authCode ); // Store the credentials to disk. if (! file_exists (dirname( $credentialsPath ))) { mkdir (dirname( $credentialsPath ), 0700, true); } file_put_contents ( $credentialsPath , json_encode( $accessToken )); printf( "Credentials saved to %s\n" , $credentialsPath ); } $client ->setAccessToken( $accessToken ); // Refresh the token if it's expired. if ( $client ->isAccessTokenExpired()) { $client ->fetchAccessTokenWithRefreshToken( $client ->getRefreshToken()); file_put_contents ( $credentialsPath , json_encode( $client ->getAccessToken())); } return $client ; } /** * Expands the home directory alias '~' to the full path. * @param string $path the path to expand. * @return string the expanded path. */ function expandHomeDirectory( $path ) { $homeDirectory = getenv ( 'HOME' ); if ( empty ( $homeDirectory )) { $homeDirectory = getenv ( 'HOMEDRIVE' ) . getenv ( 'HOMEPATH' ); } return str_replace ( '~' , realpath ( $homeDirectory ), $path ); } // Get the API client and construct the service object. $client = getClient(); $service = new Google_Service_Calendar( $client ); ?> </body> </html> |
ไฟล์โค้ดนี้ เราตัดส่วนของการแสดงรายการ event ของ calendar ออกไป แต่ยังไม่เพิ่มส่วนของคำสั่งการ
เพิ่ม event ใหม่เข้าไป
ให้เราดูตัวอย่างการเพิ่มข้อมูลใหม่จากหน้า
ส่วนของโค้ดตัวอย่างการเพิ่มข้อมูล
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | $event = new Google_Service_Calendar_Event( array ( 'summary' => 'Google I/O 2015' , 'location' => '800 Howard St., San Francisco, CA 94103' , 'description' => 'A chance to hear more about Google\'s developer products.' , 'start' => array ( 'dateTime' => '2015-05-28T09:00:00-07:00' , 'timeZone' => 'America/Los_Angeles' , ), 'end' => array ( 'dateTime' => '2015-05-28T17:00:00-07:00' , 'timeZone' => 'America/Los_Angeles' , ), 'recurrence' => array ( 'RRULE:FREQ=DAILY;COUNT=2' ), 'attendees' => array ( array ( 'email' => 'lpage@example.com' ), array ( 'email' => 'sbrin@example.com' ), ), 'reminders' => array ( 'useDefault' => FALSE, 'overrides' => array ( array ( 'method' => 'email' , 'minutes' => 24 * 60), array ( 'method' => 'popup' , 'minutes' => 10), ), ), )); $calendarId = 'primary' ; $event = $service ->events->insert( $calendarId , $event ); printf( 'Event created: %s' , $event ->htmlLink); |
ขอแยกออกมาให้เป็นภาพ และกำหนดข้อมูลสมมติ สำหรับทดสอบ โดยเปลี่ยน
ปีเป็น 2021 และ timeZone เป็น Asia/Bangkok
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /////////// ส่วนของการเพิ่ม Event // ตัวแปรโครงสร้าง parameter สำหรับสร้าง event $event_data = array ( 'summary' => 'Google I/O 2021' , // หัวเรื่อง 'location' => '800 Howard St., San Francisco, CA 94103' , // สถานที่ 'description' => 'A chance to hear more about Google\'s developer products.' , // รายละเอียด 'start' => array ( // วันที่เวลาเริ่มต้น 'dateTime' => '2021-05-28T09:00:00-07:00' , 'timeZone' => 'Asia/Bangkok' , ), 'end' => array ( // วันที่เวลาสิ้นสุด 'dateTime' => '2021-05-28T17:00:00-07:00' , 'timeZone' => 'Asia/Bangkok' , ), 'recurrence' => array ( // การทำซ้ำ 'RRULE:FREQ=DAILY;COUNT=2' ), 'attendees' => array ( // ผู้เข้าร่วม อีเมล array ( 'email' => 'lpage@example.com' ), array ( 'email' => 'sbrin@example.com' ), ), 'reminders' => array ( // การแจ้งเตือน 'useDefault' => FALSE, 'overrides' => array ( array ( 'method' => 'email' , 'minutes' => 24 * 60), array ( 'method' => 'popup' , 'minutes' => 10), ), ), ); $event = new Google_Service_Calendar_Event( $event_data ); // สร้าง event object $calendarId = 'primary' ; // calendar หลัก $event = $service ->events->insert( $calendarId , $event ); // ทำคำสั่งเพิ่มข้อมูล printf( 'Event created: %s' , $event ->htmlLink); // หากเพิ่มข้อมูลสำเร็จ จะได้ค่า ลิ้งค์ |
นำโค้ดตัวอย่างข้างต้นไปต่อท้ายในไฟล์ add_event.php แล้วรันผ่านบราวเซอร์
ผลลัพธ์ที่ได้

จะเห็นว่าคำสั่งข้างต้น ทำการสร้าง event ให้เราสำเร็จ พร้อมกับมี url ของ event ที่เพิ่งสร้าง ที่จะพา
เราไปยังหน้า event ใน google calendar ตามรูปตัวอย่าง

จากรูปคือข้อมูลตัวอย่างที่ถูกเพิ่มไปใน google calendar
ถ้าเรากลับมาเปิดไฟล์ calendar.php ก็จะแสดงข้อมูล event ที่ถูกเพิ่มเข้ามาล่าสุด 2 รายการ ของวันที่
28 และ 29

ทั้งนี้มีส่วนของการกำหนดการทำซ้ำใน parameter ด้วย นั่นคือค่า
1 2 3 | 'recurrence' => array ( // การทำซ้ำ 'RRULE:FREQ=DAILY;COUNT=2' ), |
สังเกตรูปแบบการกำหนด FREQ คือความถึ่ กำหนดเป็น DAILY และ จำนวนวัน COUNT กำหนดเป็น 2
ดังนั้นด้วยรูปแบบการกำหนดค่าการทำซ้ำ จึงมี event เพิ่มมาสองวันนั่นเอง
การลบข้อมูล Events ใน Google calendar
สำหรับการลบข้อมูล Event มีรูปแบบคำสั่งที่ง่าย ดังนี้
1 | $service ->events-> delete ( 'primary' , 'eventId' ); |
parameter ที่เราต้องส่งก็คือ calendarID กับ eventId
ในไฟล์ calendar.php เราวนลูปแสดงรายการแล้ว เราจะลองเพิ่มลิ้งค์ปุ่มสำหรับส่งค่า eventId สำหรับ
ใช้ในการลบเข้าไป และเพิ่มส่วนของคำสั่งสำหรับลบข้อมูลเข้าไปด้วย โดยปรับโค้ดเล็กน้อยดังนี้
ไฟล์ calendar.php (บางส่วน)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // Print the next 10 events on the user's calendar. $calendarId = 'primary' ; $optParams = array ( 'maxResults' => 10, 'orderBy' => 'startTime' , 'singleEvents' => TRUE, 'timeMin' => date ( 'c' ), ); // ส่วนของการลบข้อมูล if (isset( $_GET [ 'eventId' ]) && $_GET [ 'eventId' ]!= "" ){ $eventId = $_GET [ 'eventId' ]; $service ->events-> delete ( $calendarId , $eventId ); header( "Location:calendar.php" ); exit ; } // ส่วนของการดึงข้อมูลมาแสดง $results = $service ->events->listEvents( $calendarId , $optParams ); if ( count ( $results ->getItems()) == 0) { print "No upcoming events found.\n" ; } else { print "Upcoming events:\n" ; foreach ( $results ->getItems() as $event ) { $start = $event ->start->dateTime; if ( empty ( $start )) { $start = $event ->start-> date ; } printf( "%s (%s)\n" , $event ->getSummary(), $start ); print ( "<a href='?eventId=" . $event ->getId(). "'>Delete</a>" ); printf( '<br>' ); } } |
ทดสอบรันก็จะได้ผลลัพธ์ประมาณนี้

เราลองทดสอบกดลบรายการล่างสุด

รายการล่างสุดก็จะถูกลบ เหลือแค่รายการเดียวด้านบน ตอนนี้ลบออกให้หมดไปก่อนได้เลย
การประยุกต์การเพิ่ม Event ใน Google calendar ผ่าน Calendar API อย่างง่าย
จากเดิมเราทดสอบการเพิ่มข้อมูล โดยใช้ค่าที่กำหนดตายตัว เพื่อดูรุปแบบการทำงานในไฟล์
add_event.php
ต่อไป เราจะลองส่งค่าจากฟอร์มที่เราสร้างขึ้นมา เพื่อบันทึกผ่าน api ไปยัง calendar โดยในที่นี้
จะใช้รูปแบบอย่างง่าย และตัด parameter บางส่วนออกไป ปรับไฟล์ในส่วนของ add_event.php
บางส่วนเป็นดังนี้
ไฟล์ add_event.php (บางส่วน)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /////////// ส่วนของการเพิ่ม Event // ตัวแปรโครงสร้าง parameter สำหรับสร้าง event $summary = $_POST [ 'summary' ]; $description = $_POST [ 'description' ]; $start = $_POST [ 'start' ]; $end = $_POST [ 'end' ]; // ตรวจสอบอย่างง่าย ว่ามีค่าส่งมาหรือไม่ มีค่าส่งมาจึงจะทำการเพิ่มข้อมูล if ( $summary != "" && $description != "" && $start != "" && $end != "" ){ $event_data = array ( 'summary' => $summary , // หัวเรื่อง 'description' => $description , // รายละเอียด 'start' => array ( // วันที่เวลาเริ่มต้น 'date' => $start , 'timeZone' => 'Asia/Bangkok' , ), 'end' => array ( // วันที่เวลาสิ้นสุด 'date' => $end , 'timeZone' => 'Asia/Bangkok' , ), ); $event = new Google_Service_Calendar_Event( $event_data ); // สร้าง event object $calendarId = 'primary' ; // calendar หลัก $event = $service ->events->insert( $calendarId , $event ); // ทำคำสั่งเพิ่มข้อมูล printf( 'Event created: %s' , $event ->htmlLink); // หากเพิ่มข้อมูลสำเร็จ จะได้ค่า ลิ้งค์ } echo "<br>" ; echo "<a href='calendar.php'>Back to Form</a>" ; |
ต่อไปในไฟล์ calendar.php เราจะสร้างฟอร์มอย่างง่ายจากในไฟล์นี้ โดยเพิ่มโค้ดไปด้านล่างสุดของไฟล์
ไฟล์ calendar.php (บางส่วนด้านล่าง)
1 2 3 4 5 6 7 8 | <hr> <form action= "add_event.php" method= "post" > Summary:<input type= "text" name= "summary" ><br> Description:<textarea name= "description" rows= "3" cols= "50" ></textarea><br> Start Date :<input type= "date" name= "start" ><br> End Date :<input type= "date" name= "end" ><br> <button type= "submit" >Send</button> </form> |
ตัวอย่างหน้าผลลัพธ์

เราทดสอบกรอกข้อมูล ประมาณนี้ลงไป

จากนั้นกดส่งข้อมูล หากไม่มีอะไรผิดพลาดผลลัพธ์ในไฟล์ add_event.php จะเป็นดังนี้

เพิ่มกิจกรรมสำเร็จ ข้อมูลใน google calendar ก็จะประมาณนี้

เรากดลิ้งค์กลับไปที่หน้า calendar.php ก็จะแสดงรายการล่าสุดที่เราเพิ่งเพิ่มเข้าไป

แนวทางการประยุกต์ข้างต้น เป็นรูปแบบอย่างง่าย ดังนั้น หากเราต้องการให้สามารถจัดการหรือ
กำหนดรูปแบบได้มากขึ้น ให้ทำความเข้าใจกับ parameter อื่นๆ เพิ่มเติม เช่น การกำหนดการทำซ้ำ
การกำหนดการแจ้งเตือน เหล่านี้เป็นต้น