PHP script to pull from Facebook events from multiple pages - php

Bonjour everyone,
Currently, the script below is on my server as a PHP page (pull.php). It reads the events from a Facebook page using its ID, e.g: 12345678, and outputs them to a file, e.g: 1234568.ics.
What I'd like to ask this community for help with:
1) how would one modify the code below to read from many Facebook pages (an array where I would put in the page ID manually, e.g: 12345678, 24681357, 12348765) and output to many files 12345678.ics, 24682357.ics, 12348765.ics
2) I'm looking for these .ics files to be created and updated (crushed) right on my server, at the same location as where the script runs. The idea is that I'll run a CRON job that would run this script nightly. I then have a plugin on my Facebook page that updates events on the website based on the .ics feed.
CODE:
$access_token = MY_ACCESS_TOKEN;
$page = "12345678";
// We don't want to query the Facebook Graph API over and over, so we'll cache our results. You can force the cache to update by visiting the script and appending "?f=true", otherwise it will only run (rather than display the cache) if the cache is older than 3600 seconds (one hour).
$cache = $page . ".cache";
$f = false;
if($_GET['f'] == "true"){
$f = true;
}
if(!file_exists($cache) || filemtime($cache) <= time()-3600 || $f){
// Get and decode the data - your page's event list - from the API
$graph_url = "https://graph.facebook.com/" . $page . "/events?access_token=" . $access_token;
$data = file_get_contents($graph_url);
$data = json_decode($data);
if(!empty($data->error)){
echo '<b>$data error</b><br />';
echo $data->error->type . " error (" . $data->error->code . "/" . $data->error->error_subcode . "): " . $data->error->message;
exit;
}
// Go through the list of events, and get and decode more detailed information on each event.
foreach ($data->data as $event){
$event_data = file_get_contents("https://graph.facebook.com/" . $event->id . "?access_token=" . $access_token);
$event_data = json_decode($event_data);
if(!empty($event_data->error)){
echo '<b>$event_data error</b><br />';
echo $event_data->error->type . " error (" . $event_data->error->code . "/" . $event_data->error->error_subcode . "): " . $event_data->error->message;
exit;
}
// Store it in an array for later use.
$events[] = $event_data;
}
// We're now done fetching the data from Facebook's Graph API. Now we'll have to create an iCal file.
// This requires the iCalcreator PHP class, which you can downloead from kigkonsult at kigkonsult.se/iCalcreator/index.php
require_once("icalcreator/iCalcreator.class.php");
// Create the calendar, set up some basic properties
$c = new vcalendar(array('unique_id' => $page));
$c->setProperty('X-WR-CALNAME', $page . ' events');
$c->setProperty('X-WR-CALDESC', 'Facebook events for ' . $page);
$c->setProperty('X-WR-TIMEZONE', $events[0]->timezone); // We assume all of the events use the same timezone.
// Loop through the events, create event components in the calendar
foreach($events as $key => $event){
$e[$key] = & $c->newComponent('vevent');
$e[$key]->setProperty('summary', $event->name);
$e[$key]->setProperty('dtstart', $event->start_time);
$e[$key]->setProperty('dtend', $event->end_time);
if (!isset($event->end_time)) {
$e[$key]->setProperty('dtend', $event->start_time);
}
$e[$key]->setProperty('description', $event->description . "\n\nhttp://www.facebook.com/events/" . $event->id);
$e[$key]->setProperty('location', $event->location);
}
// Remove the cache if it exists
if(file_exists($cache)){
unlink($cache);
}
// Open (create) the cache file
if(!$handle = fopen($cache, 'w')){
echo "Cannot open output file: " . $cache;
exit;
}
// Write the calendar to the cache
if(fwrite($handle, $c->createCalendar()) === FALSE){
echo "Cannot write to output file: " . $cache;
exit;
}
// Close the cache file
fclose($handle);
}
// Now we've got the calendar in the cache file, either newly generated and stored there just a few lines ago or from earlier. Now we'll just display it.
header("Content-Type: text/calendar; charset=UTF-8");
header("Content-Disposition: filename=" . $page . ".ics");
require($cache);
?>
Might anyone have a clue how to do this?
Thanks in advance! Upvotes your way if you can help me out!

You can use a FQL query to get results for multiple pages at once, like this:
select eid, creator, name, description, start_time, end_time, timezone, location from event where creator in ({PAGE1_ID}, {PAGE2_ID}, ...) and start_time > now() order by creator asc
You can issue the (URL encoded) query via the
GET /fql?q=...
endpoint like this (replace Page IDs!):
http://graph.facebook.com/fql?q=select%20eid%2C%20creator%2C%20name%2C%20description%2C%20start_time%2C%20end_time%2C%20timezone%2C%20location%20from%20event%20where%20creator%20in%20(1234,5678)%20and%20start_time%20%3E%20now()%20order%20by%20creator%20asc
But then you have to restructure your code a little bit, because the result will look like the following:
{
"data": [
{
"eid": 2289962603,
"creator": 1146614804,
"name": "eventname",
"description": "descr",
"start_time": "2014-05-30T21:00:00+0200",
"end_time": null,
"timezone": "Europe/Berlin",
"location": "thelocation"
},
...
]
}
You then have to react on changes of the value for the creator field, which then indicated that there's a new calendar to be created (creator = page_id)

Related

PHP Batch upload array data

I am working with a client API (master API) that does not have a bulk feature.
I have taken data from 2 different API's (client API's) and merged it into one JSON file that is properly formatted. Checked in online JSON Validator.
The JSON File is 1100 records of merged customer data. Taking one record at a time, I have built a function that submits the data successfully to the master API.
I have now built a PHP script that loops through the JSON File and takes the row data (each client record) and submits it to the master API successfully. After about 90 rows, the PHP script times out.
I have set the following code on the page
#ini_set('zlib.output_compression', 0);
#ini_set('implicit_flush', 1);
set_time_limit(600);
#ob_end_clean();
And am buffering each update to return a JSON status code returned from the master API.
What should I be doing to get the PHP to not time out after about 100 records and keep updating the buffer response on the page.?
Thanks in advance.
Jason
I've taken a few of different approached to this kind of problem in the past. The only quick fix for this is if you can change the php.ini settings on the server to increase the timeout enough to allow your batch to complete. This is not a great solution, but it is a solution.
The next option (in ascending order of effort) is to set up a loop between the browser and your server where your browser makes a request, the server sends a portion of the records, then returns to the browser with a cursor indicating where the process left off, the browser makes another request to the server, sending the cursor back as a parameter, and this continues until the batch finishes. This is nice because you can display a progress bar to the user.
Finally, you could have an agent running on the server that waits for batch jobs to be submitted and runs them completely outside of the HTTP request lifecycle. So your browser makes a request to kick off a batch job, which results in some sort of record in a database that can keep track of the status of the job. The agent picks up the job and sets it to a pending state while it works, then sets the completion status when it finishes. You can set set something up that allows you to poll the server from the browser periodically so you can alert the user when the process finishes. Of you can just have the agent send an email report to the user when the batch completes. This is the most solid option with the least risk of something interrupting the processing, and it can leave an audit trail without any effort at all. But it's clearly more complicated to set up.
Thanks Rob.
Your response sent me in the right direction.
I sort of used your backend idea on the frontend. I just looped through 20 records at a time and then refreshed the page via javascript and started at 21 to 40 etc. Threw in a progress bar for fun as well.
Thanks for helping me get my head around the idea. Not the right way to do it, but my Python is just as bad as my PHP.
<?php
#ini_set('zlib.output_compression', 0);
#ini_set('implicit_flush', 1);
set_time_limit(600);
#ob_end_clean();
require("header.php");
require_once('nav.php');
function sync_systems($sfData){
$dataPost = $sfData;
$postID = $dataPost['ID'];
$epcall = update_profile($dataPost);
$epResult = json_decode($epcall, true);
if($epResult['status'] != 404){
$sfStatus = updateSFOpportunity($epResult['client_id'], $epResult['ep_id'] );
if($sfStatus == 1){
$datamsg = " Success! The sync was a success in both Salesforce and other system. OtherSystem Record " . $epResult['ep_id'] . " was created or updated.<br/>";
} else {
$datamsg = " Success! The sync was a success in other system, but failed in Salesforce<br/>";
}
echo json_encode(['code'=>200, 'msg'=>$datamsg]);
} else {
$datamsg = " Failure! The sync did not work.<br/>";
echo json_encode(['code'=>404, 'msg'=>$datamsg]);
} // end epResult
}
function sync_ep($sfData){
$dataPost = $sfData;
$postID = $dataPost['ID'];
$epcall = update_profile($dataPost);
$epResult = json_decode($epcall, true);
if($epResult['status'] != 404){
// $sfStatus = updateSFOpportunity($epResult['client_id'], $epResult['ep_id'] );
if($sfStatus == 1){
$datamsg = " Success! The sync was a success in both Salesforce and other system. Other System Record " . $epResult['ep_id'] . " was created or updated.<br/>";
} else {
$datamsg = " Success! The sync was a success in other system, but failed in Salesforce<br/>";
}
echo json_encode(['code'=>200, 'msg'=>$datamsg]);
} else {
$datamsg = " Failure! The sync did not work.<br/>";
echo json_encode(['code'=>404, 'msg'=>$datamsg]);
} // end epResult
}
$ju = "CustomerData20Fall.json";
//read json file from url in php
$readJSONFile = file_get_contents($ju);
//convert json to array in php
$jfile = json_decode($readJSONFile);
//print_r($jfile);
//convert json to array in php
$epSync = array();
$oldValue = 0;
$total = count($jfile );
?>
<!-- Progress bar holder -->
<div id="progress" style="width:500px;border:1px solid #ccc;"></div>
<!-- Progress information -->
<div id="information" style="width"></div>
<?php
if(isset($_REQUEST["NEXTVALUE"])){
$nextValue = $_REQUEST["NEXTVALUE"];
} else {
$nextValue = 1;
}
$refreshValue = $nextValue + 20;
$displaycounter = $nextValue;
$timeRemaining = 0;
$updatedRecords = 0;
foreach ($jfile as $key => $jsons) {
$newKey = $key;
if($oldValue != $newKey){
if($newKey >= $nextValue && $newKey < $refreshValue){
// echo "Updated: " . [$oldValue]['EPID'] . "<br/>";
// echo "<hr>" . $nextValue . " >= " . $newKey . " < " . $refreshValue;
print_r($epSync[$oldValue]);
$displaycounter = $newKey;
echo sync_systems($epSync[$oldValue]);
usleep(30000);
flush();
} else {
if($key == ($refreshValue)){
$theURL = "sf-ep-sync.php?NEXTVALUE=" . $refreshValue . "&RAND=" . rand();
// echo "<hr>" . $newKey . " = " . $refreshValue . " " . $theURL ."<br/>";
echo "<script>location.href = '" . $theURL . "';</script>";
exit;
}
}
$oldValue = $newKey;
$i = $nextValue + 1;
if(($i + 1) == $total ){
$percent = intval($i/$total * 100)."%";
$timeRemaining = 0;
} else {
$percent = intval($i/$total * 100)."%";
$timeRemaining = (($total - $displaycounter)/60);
}
usleep(30000);
echo '<script language="javascript">
document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\"> </div>";
document.getElementById("information").innerHTML="'.$displaycounter.' row(s) of '. $total . ' processed. About ' . round($timeRemaining, 2) . ' minutes remaining.";
</script>';
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
}
foreach($jsons as $key => $value) {
$epSync[$newKey][$key] = $value;
}
}
Thanks,
Jason

jQuery dataTables not loading AJAX JSON data

I have a table that is populated via dataTables with information from a MySQL table. The information is prepared via PHP as proper JSON in the way dataTables expects the information.
The problem I'm having is the table no longer loads informations. Even reverting my changes so that the JSON data does not include links to the server description (via view.php) doesn't change anything.
The site can be found here: checkersthecat.com/status The PHP that outputs JSON information can be found here: checkersthecat.com/status/inc/json-servers.php
Here is the code for json-servers.php
<?php
$db = new PDO("mysql:host=localhost;dbname=mcstatus;charset=UTF8", "user", "pass");
$stmt = $db->prepare("SELECT ip, port, category, players, tries, description FROM clients");
$stmt->execute();
$servers = $stmt->fetchAll(PDO::FETCH_ASSOC);
$count = $stmt->rowCount();
$data = array(
"aaData" => array()
);
foreach ($servers as $item) {
$arr = array();
// Address
if (strlen($item['description']) == 0) {
if ($item['port'] != 25565) {
array_push($arr, $item['ip'] . ":" . $item['port']);
} else {
array_push($arr, $item['ip']);
}
} else {
if ($item['port'] != 25565) {
array_push($arr, "<a href='inc/view.php?ip=" . $item['ip'] . "'>" . $item['ip'] . ":" . $item['port'] . "</a>");
} else {
array_push($arr, "<a href='inc/view.php?ip=" . $item['ip'] . "'>" . $item['ip'] . "</a>");
}
}
// Category
array_push($arr, $item['category']);
// Status
if ($item['tries'] == 0) {
array_push($arr, "Up");
} else {
array_push($arr, "Down (" . $item['tries'] . ")");
}
// Players
if ($item['players'] == -1) {
array_push($arr, "?");
} else {
array_push($arr, $item['players']);
}
array_push($data['aaData'], $arr);
}
header("Content-type: application/json");
echo json_encode($data);
?>
The snippet of javascript that actually initializes and sets up the dataTable is here:
// init load of table
serverTable = $("#servers").dataTable({
"bProcessing": true,
"bStateSave": true,
"sPaginationType": "two_button",
"sAjaxSource": "http://checkersthecat.com/status/inc/json-servers.php"
});
It literally worked, I changed one small item relating to the description length in the javascript relating to a jQuery modal dialog form, I refreshed the page, and suddenly dataTables no longer loads my JSON information.
I'm at a total loss as to why it will not work. Even reverting to my old code without the hyperlinks in the JSON data and previous description limits doesn't make a difference. It still gives me an endless "Processing" and "Loading". When I try to search it merely says "No data available" which is ludicrous as the JSON information is right there at the URL and is valid.
I've tried debugging the javascript and PHP with firebug and turning on error reporting respectively, but apparently there isn't anything wrong with it all as far as I know.
Any help is very appreciated as this has had me tearing my hair out. If there's any other details that you may need, please let me know.
It works, but I'm unsure what exactly the problem was.

Inserting Events to google calendar from a script

Anyone know the proper way to authenticate and publish directly to a calendar without relying on a currently logged in user? Several weeks ago I built a calendar that used the standard Oauth 2.0 protocol but this relied sessions stored by a user's we browser. I have one calendar that I want to pass events to from an application I am writing with a basic PHP framework. I'm more concerned with what are the best practices that others are using. Your answer could be simply, don't do it. Thanks alot.
Use OAuth 2 and the Authorization Code flow (web server flow), with offline enabled. Store the refresh tokens (which last indefinitely until the user has revoked), and you'll be able to upload events to Google Calendar even when the user isn't currently logged in.
More info:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
try Zend_Gdata_Calendar with this library you are able to insert or get events from any user(with the right username and password obviously) from google calendar and integrate with your own calendar or display it..here a short example:
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient('gmail#user.com', 'gmailpassword', $service);
$service = new Zend_Gdata_Calendar($client);
$query = $service->newEventQuery();
$query->setUser('default');
$query->setVisibility('private');
try {
$eventFeed = $service->getCalendarEventFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: " . $e->getMessage();
}
echo "<ul>";
foreach ($eventFeed as $event) {
echo "<li>" . $event->title . " (Event ID: " . $event->id . ")</li>";
}
echo "</ul>";
$eventURL = "http://www.google.com/calendar/feeds/default/private/full/Dir0FthEpUbl1cGma1lCalendAr";
try {
$event = $service->getCalendarEventEntry($eventURL);
echo 'Evento: ' . $event->getTitle() .'<br>';
echo 'detalles: ' . $event->getContent().'<br>';
foreach ($event->getWhen() as $dato)
{
echo 'inicia: ' . substr($dato->startTime, 0,-19) . ' a las: ' . substr($dato->startTime, 11,-10) .'<br>';
echo 'termina: ' .substr($dato->endTime,0,-19) . ' a las: ' . substr($dato->endTime,11,-10) .'<br>';
}
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: " . $e->getMessage();
}
with this you can add, update, edit or delete events from calendar form any user with mail and password...

IRC related help

Now I have my bot to send message when the bot joins. However how do I make a form that would post data so that the bot will say the message to the channel?
Here is my script (Rewamped):
<?php
set_time_limit(0);
$socket = fsockopen("//", 6667) or die();
$msg = $_POST['message'];
$pr = $_POST['percentage'];
$pr /= 100;
fputs($socket,"USER BOT 0 zo :ZH bot\n");
// Set the bots nickname
fputs($socket,"NICK BOT1\n");
fputs($socket,"JOIN #bots\n");
while(1) {
while($data = fgets($socket, 128)) {
// echo the data received to page
echo nl2br($data);
// flush old data, it isn't needed any longer.
flush();
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
$search_string = "/^:([A-Za-z0-9_\-]+)[#!~a-zA-Z0-9#\.\-]+\s*([A-Z]+)\s*[:]*([\#a-zA-Z0-9\-]+)*\s*[:]*([!\#\-\.A-Za-z0-9 ]+)*/";
$do = preg_match($search_string, $data, $matches);
// check that there is a command received
if(isset($matches['2'])) {
switch($matches['2']) {
case "PRIVMSG":
$user = $matches['1'];
$channel = $matches['3'];
$chat_text = isset($matches['4']) ? $matches['4'] : "";
// check chat for !time
if(strtolower($chat_text) == "!time") {
$output = "::::: " . date('l jS \of F Y h:i:s A') . " :::::";
fputs($socket, "PRIVMSG " . $channel . " :" . $output . "\n");
} elseif(strtolower($chat_text) == "!hello") {
fputs($socket, "PRIVMSG " . $channel . " :Hello!\n");
}
break;
case "JOIN":
$user = $matches['1'];
$channel = $matches['3'];
fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel . "\n");
break;
}
}
}
}
?>
E.g. Making a form that would send the data to the IRC channel. The output would be "wget file info port" <-- That would be the text sent to the IRC channel.
Here are parts related:
fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel ."\n");
Hope someone can help out.
Okay here's a better answer. The first section still stands. A new PHP process is called every time you want to initiate a new script. Thus, you need some way to do IPC.
Here's how it's done on *nix (but not windows) in PHP:
Receiver:
<?php
$queueKey = 123321;
$queue = false;
if(msg_queue_exists($queueKey)) {
echo "Queue Exists.\n";
}
// Join the queue
$queue = msg_get_queue($queueKey);
while(!($queue == false)) {
// Note: This function could block if you feel like threading
$msgRec = msg_receive(
$queue, // I: Queue to get messages from
0, // I: Message type (0 = first on queue)
$msgType, // O: Type of message received
1024, // I: Max message size
$msgData, // O: Data in the message
true, // I: Unserialize data
MSG_IPC_NOWAIT // I: Don't block
);
if($msgRec) {
echo "Message received:\n";
echo "Type = $msgType\n";
echo "Data = \n";
print_r($msgData);
}
}
?>
Sender:
<?php
$queueKey = 123321;
$queue = false;
if(msg_queue_exists($queueKey)) {
echo "Queue Exists.\n";
} else {
echo "WARNING: Queue does not exist. Maybe no listeners?\n";
}
$queue = msg_get_queue($queueKey);
$abc["something"] = "something value";
$abc["hello"] = "world";
$abc["fu"] = "bar";
msg_send(
$queue, // Queue to send on
1, // Message type
$abc, // Data to send
true, // Serialize data?
true // Block
);
?>
This should produce (in the receiver loop) something similar to this:
Message received:
Type = 1
Data =
Array
(
[something] => something value
[hello] => world
[fu] => bar
)
Your script might look something like this
postToMe.php:
<?php
$queueKey = 123321;
$queue = false;
if(msg_queue_exists($queueKey)) {
echo "Queue Exists.\n";
} else {
echo "WARNING: Queue does not exist. Maybe no listeners?\n";
}
$queue = msg_get_queue($queueKey);
msg_send(
$queue, // Queue to send on
1, // Message type
$_POST, // Data to send
true, // Serialize data?
true // Block
);
?>
bot.php:
<?php
set_time_limit(0);
$socket = fsockopen("//", 6667) or die();
$msg = $_POST['message'];
$pr = $_POST['percentage'];
$pr /= 100;
fputs($socket,"USER BOT 0 zo :ZH bot\n");
// Set the bots nickname
fputs($socket,"NICK BOT1\n");
fputs($socket,"JOIN #bots\n");
$queueKey = 123321;
$queue = false;
// Join the IPC queue
$queue = msg_get_queue($queueKey);
if(!$queue) echo "ERROR: Could not join IPC queue. Form data will not be received";
while(1) {
// Handle new post info
// You may want to increase the message size from 1024 if post data is large
if(msg_receive($queue, 0, $msgType, 1024, $msgData, true, MSG_IPC_NOWAIT)) {
// Handle data here. Post data is stored in $msgData
}
while($data = fgets($socket, 128)) {
// echo the data received to page
echo nl2br($data);
// flush old data, it isn't needed any longer.
flush();
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
$search_string = "/^:([A-Za-z0-9_\-]+)[#!~a-zA-Z0-9#\.\-]+\s*([A-Z]+)\s*[:]*([\#a-zA-Z0-9\-]+)*\s*[:]*([!\#\-\.A-Za-z0-9 ]+)*/";
$do = preg_match($search_string, $data, $matches);
// check that there is a command received
if(isset($matches['2'])) {
switch($matches['2']) {
case "PRIVMSG":
$user = $matches['1'];
$channel = $matches['3'];
$chat_text = isset($matches['4']) ? $matches['4'] : "";
// check chat for !time
if(strtolower($chat_text) == "!time") {
$output = "::::: " . date('l jS \of F Y h:i:s A') . " :::::";
fputs($socket, "PRIVMSG " . $channel . " :" . $output . "\n");
} elseif(strtolower($chat_text) == "!hello") {
fputs($socket, "PRIVMSG " . $channel . " :Hello!\n");
}
break;
case "JOIN":
$user = $matches['1'];
$channel = $matches['3'];
fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel . "\n");
break;
}
}
}
}
?>
Basically, this script will be running all the time. The way PHP works is that for each script that is being run, a new PHP process is created. Scripts can be run multiple times simultaneously, however they will not be able to directly communicate.
You will need to create enother script (or at least a whole new function of this one) to accept the post variables, and then send them to the running version of this script.
(Note: I will provide 2 solutions, since 1 is significantly more difficult. Also, there's Semaphore that I've just found, however I am unsure exactly if this suits our needs because I know next to nothing about it http://php.net/manual/en/book.sem.php)
Best (But Advanced)
The best way I can think of doing this would be to use sockets (particularly on *nix, since sockets are fantastic for IPC [inter process communication]). It's a little difficult, since you're basically create a client/server just to communicate details, then you need to come up with some sort of a protocol for your IPC.
I won't code anything up here, but the links that are relevant to this are
http://www.php.net/manual/en/function.socket-create.php
http://www.php.net/manual/en/function.socket-bind.php
http://www.php.net/manual/en/function.socket-listen.php
http://www.php.net/manual/en/function.socket-accept.php
http://www.php.net/manual/en/function.socket-connect.php
If using this on *nix, I would highly recommend using AF_UNIX as the domain. It's very efficient, and quite a number of applications use it for IPC.
Pros:
Very robust solution
- Highly efficient
- Instant (or as close as we can get) communication
Cons:
- Quite difficult to implement
Not As Great (But Still Good)
Just use files to communicate the information. Have your bot script check the file every 15 seconds for changes. I would suggest using XML for the data (since simple xml makes xml processing in php well... simple)
Things you need to consider would be:
How would it react when receiving 2 posts at the same time? (If you just use a flat file or don't account for having multiple entries, this will become a problem).
How you find out if a message is new (I'd delete/blank the file right after reading. Note: Not after processing, as someone could post to the form script while you are processing/sending the message)
Links:
How to use simple xml
http://php.net/manual/en/simplexml.examples-basic.php
http://au2.php.net/manual/en/book.simplexml.php
File related
http://au2.php.net/manual/en/function.file-put-contents.php
http://au2.php.net/manual/en/function.file-get-contents.php
With that being said, you could also use MySQL/Postgres or some other database back end to deal with the flow of data between scripts.
Pros:
- Easy to implement
Cons:
- Slow to transfer data (checks files at given intervals)
- Uses external files, which can be deleted/modified my external applications/users

Google Calendar PHP - Event URL / ID? (Zend_Gdata)

I have modified my PHP web app to add events to a Google Calendar. Currently, it adds successfully.
However, now I wish to delete and edit events. This seems easy to do, except for the fact that I don't know what event URL is associated with each event.
Am I supposed to set this event URL (or ID?) upon adding an event? How am I supposed to figure out what it is?
I can't seem to find this information anywhere else...
Thanks!
EDIT:
I have been using the Zend Framework for this (Gdata package)...
EDIT:
$newIncludePath = array();
$newIncludePath[] = '../ZendGdata-1.8.4PL1/library';
$newIncludePath = implode($newIncludePath);
set_include_path($newIncludePath);
// load classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
Zend_Loader::loadClass('Zend_Http_Client');
// connect to service
$gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$user = "********#gmail.com";
$pass = "*****";
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $gcal);
$gcal = new Zend_Gdata_Calendar($client);
// construct event object
// save to server
try {
$event = $gcal->newEventEntry();
$event->title = $gcal->newTitle($title);
$event->content = $gcal->newContent($desc);
$when = $gcal->newWhen();
$when->startTime = $date;
$when->endTime = $date;
$event->when = array($when);
$gcal->insertEvent($event);
echo $event->getEditLink()->href;
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: Unable to add event to Google Calendar" . $e->getResponse();
}
This is plainly documented in the Zend_Gdata documentation:
http://framework.zend.com/manual/en/zend.gdata.calendar.html#zend.gdata.calendar.deleting_events
// Option 1: Events can be deleted directly
$event->delete();
or
// Option 2: Events can be deleted supplying the edit URL of the event
// to the calendar service, if known
$service->delete($event->getEditLink()->href);
It sounds like you need the latter.
Edit:
Get the edit link from your $event. It's shown in the code above:
$event->getEditLink()->href;
This will be available on a saved event. e.g.
$newEvent = $service->insertEvent($event);
echo $newEvent->getEditLink()->href;
You could have a look at Zend_Gdata and Zend_Gdata_Calendar : those would probably help for all the hard work -- and if you don't have to spend code to communicate with Google's API, it gives you more time to develop other things ;-)
And it seems it can be used outsid of the Zend FRamework : it's even available as a standalone download : http://framework.zend.com/download/gdata
(If you really want to do it yourself, you can still try to understand how Zend_Gdata does it ^^ )
Here's a GREAT resource to help you with this:
Integrate your PHP application with Google Calendar
Here's how I obtain the unique ID of the calendar event after publishing the event with newEventEntry. I store the $id value in the database, in case I have to edit it later with update or delete.
try {
$event = $gcal->newEventEntry();
$event->title = $gcal->newTitle($title);
$when = $gcal->newWhen();
$when->startTime = $start;
$when->endTime = $end;
$event->when = array($when);
$gcal->insertEvent($event);
$id = substr($event->id, strrpos($event->id, '/')+1); // trim off everything but the id
} catch (Zend_Gdata_App_Exception $e) {
echo "Error: " . $e->getResponse();
}
// Do mysql Insert functions here to store the record in db (removed for clarity)
echo 'Event '. $id. 'successfully added!';
Then, when I need to access that particular event I can use it to target just that event for updating/deleting using a $_POST of the ID:
try {
$event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/feeds/default/private/full/' . $_POST['id']);
$event->title = $gcal->newTitle($title);
$when = $gcal->newWhen();
$when->startTime = $start;
$when->endTime = $end;
$event->when = array($when);
$event->save();
} catch (Zend_Gdata_App_Exception $e) {
die("Error: " . $e->getResponse());
}
echo 'Event successfully modified!';
Hope this answers your question - I struggled with getting this working, but share my findings with you here, if it helps I'm happy to have assisted.
Scott
Well if you dont want to store event ids in local database, here another good way to deleting event if you have infomration about start time, end time and calendar id(specific calendar for which you want to delete event between start time and end time)
function deleteEvent($client,$startDate,$endDate,$startTime,$endTime,$tzOffset,$cal_id)
{
$gdataCal = new Zend_Gdata_Calendar($client);
$query = $gdataCal->newEventQuery();
$query->setUser($cal_id);
$query->setVisibility('private');
$query->setProjection('full');
$query->setOrderby('starttime');
$query->setStartMin("{$startDate}T{$startTime}:00.000{$tzOffset}");
$query->setStartMax("{$endDate}T{$endTime}:00.000{$tzOffset}");
$eventFeed = $gdataCal->getCalendarEventFeed($query);
foreach ($eventFeed as $event) {
$event->delete();
}
}
Hope it helps to somebody, like it did to me.

Categories