I have a property website where I have listed multiple properties. Each property has a Google Calendar and when the property is booked on that particular day, then a note is added on that day for that particular calendar.
I was doing all this manually, where I was updating the HTML of the website by showing the availability with a layout like this.
Now I am trying to make all this automated by using the Google Calendar API where I can display the booking of each property in a calendar like the example above.
I am trying to use the Google API PHP Client Library which is located at https://github.com/google/google-api-php-client
My biggest problem here is that I am unable to find any basic example of this also over the internet. Google pages are not showing the full examples.
For example, the guide page of Google shows just one example of "books", which I don't need at all.
I have searched all over the internet for some basic examples of the code but unable to find it at all. I search stackoverflow itself but all the codes that I have find are really confusing and all of them are different.
Moreover, most of them already "know" about it so there is no way to understand what is required.
If someone has a simple example where I can pull events of a day of a calendar, please post it here.
Also if you know of some other way to display the availability like the image above, would be great help !
Thanks.
What the heck, I'll repost an answer I gave from this question:
if($refresh_token_accessed_from_my_database) {
//If session contains no valid Access token, get a new one
if ($client->isAccessTokenExpired()) {
$client->refreshToken($refresh_token_accessed_from_my_database);
}
//We have access token now, launch the service
$this->service = new Google_Service_Calendar($client);
}
else {
//User has never been authorized, so let's ask for the ok
if (isset($_GET['code'])) {
//Creates refresh and access tokens
$credentials = $client->authenticate($_GET['code']);
//Store refresh token for further use
//I store mine in the DB, I've seen others store it in a file in a secure place on the server
$refresh_token = $credentials['refresh_token'];
//refresh_token->persist_somewhere()
//Store the access token in the session so we can get it after
//the callback redirect
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
if (!isset($_SESSION['access_token'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$this->service = new Google_Service_Calendar($client);
}
When I built my project I started from the tutorial Morfinismo post in the comments, but I had a couple of problems following that one. I've made comments to describe the general flow and some potential problem points, you may want to compare those notes with the other tutorial if you're not too clear about what is going on.
Related
This is giving me quite some headache. I have an page-tab-application, where DB-interaction uses the facebook-user-id to assign and save data and also to check user permissions. Until a weak ago everything was working fine, but now with the upcoming december-changes this setup doesnt work anymore:
config.php:
$facebook = new Facebook( array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
index.php:
includes config.php and gets the signed request (not important for the question
javascript.js:
calls the read-user-status.php and handles the data
read-user-status.php:
gives json-response, includes config.php and calls the $facebook -> getUser()-function to get the uid
Even when called from the index.php directly after page-load, I sometimes get the uid and sometimes I don't. Strangly enough I usually have to wait a little until I reload the page and then it works again. But this isn't always the case. This all is just very strange to me.
EDIT: Should have mentioned that this call:
$uid = $facebook -> getUser();
if ($uid) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook -> api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$uid = FALSE;
echo "EXCEPTION $e";
}
}
gives out "EXCEPTION An active access token must be used to query information about the current user".
I know there quite a lot of similar questions out there, but none of the answers were helpful to my particular (and probably to the new breaking changes relied) problem.
EDIT2: I now suppose that it is a sdk-bug (https://developers.facebook.com/bugs/238039849657148 , thanks to CBroe). Any recommendations for a work-around are of course very welcome.
EDIT 3, TEMPORARY SOLUTION
Everytime you make an ajax request, you post the token you get from the FB.getLoginStatus or FB.login and read it out in the php file and set it via $facebook -> setAccessToken. Not suitable in all circumstances (you definately need to use post), is slower and brings some security issues, but still works.
Sounds like you are affected by the bug I reported beginning of November, https://developers.facebook.com/bugs/238039849657148
They’ve confirmed it and say they’re working on a fix – but since the change is only a few days away now, they should hurry up a little …
I got this working by doing the following...
if(!$user){
$loginUrl = $facebook->getLoginUrl(array(
'scope' => 'email',
'redirect_uri' => $app_url
));
header('Location: ' . $loginUrl);
}
I also added my app to be integrated with:
Website with Facebook login
App on Facebook
Page Tab
try by adding access token to request.
$accessToken = $facebook->getAccessToken();
$user_profile = $facebook->api('/me?access_token=' . $accessToken);
I found a work-around for this, until it is fixed (which it seems like, wont be in time until the changes take place).
Everytime you make an ajax request, you post the token you get from the FB.getLoginStatus or FB.login and read it out in the php file and set it via $facebook -> setAccessToken. Not suitable in all circumstances (you definately need to use post), is slower and brings some security issues, but still works.
if it you are lucky and your version of php sdk still registers session variables than right after _graph method declaration:
//find this method below
protected function _graph ($path, $method = 'GET', $params = array ())
{
//paste right after _graph method declaration code below:
if (isset($_SESSION["fb_".$this->getAppId()."_access_token"]))
{
$this->setAccessToken($_SESSION["fb_".$this->getAppId()."_access_token"]);
}
//till here
//and you are good to go
//remember: your version of sdk must be registering access token variable in session
//right after ajax call
//i used git to get version before last commit of sdk published on github
I am currently working on a project based on Symfony 1.4. I am using the sfDoctrineGuardPlugin to authenticate my two kinds of users : users and admins. For each module and each action in a module, I am using credentials to prevent unauthorized actions execution.
But I am facing a problem : if an user wants to edit a project, for example, the URL will look like frontend.php/project/edit/id/1. Here, we suppose that the project #1 belongs to him. Now, let's suppose that project #2 does not belong to him. If he types the URL frontend.php/project/edit/id/2, he will have access to the edit form, and will be able to edit a project that does not belong to him.
How can I prevent that behaviour ?
I would like to avoid verifying the ownership of each editable model before displaying the edit form... But can I do differently ?
Do you have any good practice or advices to prevent this behaviour ?
Thanks a lot !
Since you will have to check in the projet to know if the current user is allowed to edit the project, I don't think you will have other way than verifying before the edit, in the action part. Why don't you want to do it this way?
This check can be done inside the preExcute function:
public function preExecute()
{
$request = $this->getRequest()
if ($request->hasParameter('id'))
{
$project = Doctrine_Core::getTable('Project')->find($request->getParameter('id'));
$user_id = $this->getUser()->getGuardUser()->getId();
$this->forward404If(
$project->getUserId() !== $user_id,
'User #'.$user_id.' is not allowed to edit project #'.$project->getId()
);
}
}
In drupal how to display the user's last login date and Time.I tried out the code
user->login
It displays the current login time, But I want users previous login time and date.
Take a look at the User Stats module, it might be something that could work for you. From the module's project page:
Provides commonly requested user statistics for themers, IP address tracking and Views
integration. Statistics are:
Days registered
Join date
Days since last login
Days since last post
Post count
Login count
User online/offline
IP address
These data are saved with module Login History
Drupal doesn't offer this natively. If you need to use it, you would probably want to add it to for example serialized $user->data array when user logs in (Using hook_user() for $op = "login") and save updated user object afterwards, and then you will be able to fetch it on the next login.
The solution I used: keep track of the last two log-in timestamps (the current and the previous one).
/**
* Implementation of hook_user()
*/
function your_module_user($op, &$edit, &$account, $category = NULL) {
switch($op) {
// Successful login
case 'load':
// If it's less than two it means we don't have a previous login timtestamp yet.
$account->custom_last_login = sizeof($account->custom_login_history) < 2
? NULL
: array_pop($account->custom_login_history);
break;
case 'login':
// If it's the first time, we don't have a history
$login_history = is_array($account->custom_login_history)
? $account->custom_login_history
: array();
// Get rid of the old value.
if (sizeof($login_history) == 2) {
array_pop($login_history);
}
// Add to the history the current login timestamp.
array_unshift($login_history, $account->login);
user_save($account, array('custom_login_history' => $login_history));
break;
}
}
Then in your template you just use $user->custom_last_login. If it's empty it means we don't have the previous timestamp yet, will be available after the next login.
i'm developing an application that'll be played by different's users, but i'm using the as3 graph api for authenticating users and posting on their wall, and i need to logout each user, before next user start his session on as3 graph api:
http://code.google.com/p/facebook-actionscript-api/
I search to force FB to ask for login's info but after a logout when login again, API skip the step and log, on the last user session.
None of the solutions I have seen on the web did work for me. The problem is indeed with StageWebView facebook cookie not being cleared on logout with FacebookMobile.logout() call. Loading logout.php with access token did not help me probably because there is no "next" parameter value for air applications that makes sense. I have seen people suggest to use localhost or facebook.com there but none of these options worked.
I have come up with a really questionable solution, but it works for now.
The point is to logout user in facebook normally like he would logout on his own. To do this we need to load facebook.com in StageWebView and click logout. Logout button is a submit form item for "logout_form" html form. So we need to make a javaScript call
document.getElementById('logout_form').submit();
in our StageWebView. And we can do just that by calling
webView.loadURL("javascript:document.getElementById('logout_form').submit();");
in ActionScript.
The full code that I use for now
protected var _logoutAttemptInProgress:Boolean = false;
public function fbLogout():void{
if(!_isLoggedIn) return;
if(_logoutAttemptInProgress) return;
_logoutAttemptInProgress = true;
var webView:StageWebView = new StageWebView();
webView.viewPort = new Rectangle(-1, 0, 1, 1);
webView.stage = this.stage;
webView.loadURL("http://www.facebook.com/lksmlrsgnlskn");
webView.addEventListener(Event.COMPLETE, runLogoutJs);
function runLogoutJs(event:Event):void{
webView.removeEventListener(Event.COMPLETE, runLogoutJs);
var jsString:String = "document.getElementById('logout_form').submit();";
webView.loadURL("javascript:"+jsString);
webView.addEventListener(Event.COMPLETE, closeWebView);
}
function closeWebView(event:Event):void{
webView.removeEventListener(Event.COMPLETE, closeWebView);
webView.stage = null;
webView.dispose();
_isLoggedIn = false;
_logoutAttemptInProgress = false;
}
FacebookDesktop.logout(null, APP_ORIGIN);
}
"lksmlrsgnlskn" is just some random garbage to get to error page that is much smaller than main page and loads faster.
FacebookDesktop.logout is to clear any local SharedObject data that Facebook lib might still have.
This is an issue that's been continuously revised by FacebookMobile, Facebook, and FacebookDesktop. Basically, you'll need to make sure you set FacebookDesktop.manageSession = false; and pass in the 2nd argument of "logout" your site's api url. If that doesn't work, the other method is to use "reallyLogout", as detailed here in this thread.
The notes in comment #24 detail the way to expos the Access Token from FacebooMobile (or whichever singleton you're using), and then manually calling the logout.php method on Facebook, with the access token.
http://code.google.com/p/facebook-actionscript-api/issues/detail?id=297#c24
This is a problem with the cookies, i mean, the firts user session remains and when you press to login the API logs in the first user.
I dont know why but the Facebook Api log out method dont log the user out of facebook, only log the user out from your application.
If you came to a solution or think something else, let me know so we could get the solution.
We have tracking in our emails to track clicks back to our site through Google Analytics. But is there a way to track opens? I would imagine I have to add a google tracking image to the email somewhere. Possibly javascript too?
As others have pointed out, you can't use Javascript in email. The actual tracking is done by a request for __utm.gif though and the Javascript just constructs the GET parameters.
Google supports non-Javascript uses of Google Analytics per their Mobile web docs:
http://code.google.com/mobile/analytics/docs/web/
They document the full list of parameters, but the only necessary parameters are:
Parameter Description
utmac Google Analytics account ID
utmn Random ID to prevent the browser from caching the returned image
utmp Relative path of the page to be tracked
utmr Complete referral URL
The reference that describes all of the parameters that the Google Analytics tracking GIF allows is here. Use it to build an <img> tag in your email that references the GA GIF.
According to this post, the minimum required fields are:
utmwv=4.3
utmn=<random#>&
utmhn=<hostname>&
utmhid=<random#>&
utmr=-&
utmp=<URL>&
utmac=UA-XXXX-1&
utmcc=_utma%3D<utma cookie>3B%2B_utmz%3D<utmz cookie>%3B
It sounds like you are using campaign tracking for GA but also want to know how many opens there were. This is possible to do with Google Analytics, since they track pageviews or events by use of pixel tracking as all (I think?) email tracking does. You cannot use javascript, however, since that will not execute in an email.
Using Google Analytics pixel tracking:
The easiest way would be to use browser developer tools such as Firebug for Firefox or Opera's Dragonfly to capture a utm.gif request and copy the URL. Modify the headers to suit your needs. You can count it either as an event or pageview. If you count it as an event it should look something like this:
http://www.google-analytics.com/__utm.gif?utmwv=4.8.6&utmn=1214284135&utmhn=www.yoursite.com&utmt=event&utme=email_open&utmcs=utf-8&utmul=en&utmje=1&utmfl=10.1%20r102&utmdt=email_title&utmhid={10-digit time code}&utmr=0&utmp=email_name&utmac=UA-{your account}
You can use this to understand what describes what in the headers.
I better post this to save everyone the trouble of trying to construct that monstrous UTM gif URL.
You can now use the new Measurement Protocol API to send a POST request and easily record events, page views, hits, or almost any other type of measurement. It's super easy!
POST /collect HTTP/1.1
Host: www.google-analytics.com
payload_data
For example, here's a code snippet to send an event in C# (using SSL endpoint):
public void SendEvent(string eventCategory = null, string eventAction = null, string eventLabel = null, int? eventValue = null)
{
using(var httpClient = new HttpClient() {BaseAddress = new Uri("https://ssl.google-analytics.com/")}) {
var payload = new Dictionary<string, string>();
// Required Data
payload.Add("v", "1"); // Version
payload.Add("tid", "UA-XXX"); // UA account
payload.Add("aip", "1"); // Anonymize IP
payload.Add("cid", Guid.NewGuid().ToString()); // ClientID
payload.Add("t", "event"); // Hit Type
// Optional Data
payload.Add("ni", "1"); // Non-interactive hit
// Event Data
if (eventCategory != null)
{
payload.Add("ec", eventCategory);
}
if (eventAction != null)
{
payload.Add("ea", eventAction);
}
if (eventLabel != null)
{
payload.Add("el", eventLabel);
}
if (eventValue != null)
{
payload.Add("ev", eventValue.Value.ToString(CultureInfo.InvariantCulture));
}
using (var postData = new FormUrlEncodedContent(payload))
{
var response = httpClient.PostAsync("collect?z=" + DateTime.Now.Ticks, postData).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception("Could not send event data to GA");
}
}
}
}
Way easier than the hack with the __utm gif.
Helpful Example
You can easily add this to emails by doing this:
In an email:
<img src="{url}/newsletter/track.gif?newsletterName=X" />
In your MVC site, for example, NewsletterController:
public ActionResult Track(string newsletterName) {
using(var ga = new AnalyticsFacade()) {
ga.TrackEmailOpen(newsletterName);
}
return Content("~/images/pixel.gif", "image/gif");
}
In your Global.asax or RouteConfig:
routes.MapRoute(
"newsletteropen",
"newsletter/track.gif",
new
{
controller = "Newsletter",
action = "Track"
});
BOOM, done, son. You can now track email opens using a much nicer API that's supported and documented.
Is your requirement is to track how many times an e-mail is open by given user. We have similar problem. We are using SMTP relay server and wanted to track how many times our marketing e-mails are open in addition to google-analytics which register an even only when someone clicks inside link to our site in e-mail.
This is our solution. It is based on making a REST call by overriding image element of html (our e-mails are html base)
where TRACKING is dynamically generated url which points to our REST service with tracking information about person to which e-mail was send. It is something like that
//def trackingURL = URLEncoder.encode("eventName=emailTracking&entityType=employee&entityRef=" + email.empGuid, "UTF-8");
trackingURL = baseUrl + "/tracking/create?" + trackingURL;
It will be something like "https://fiction.com:8080/marketplace/tracking/Create?eventName=email&entityType=Person&entityRef=56"
When when actual e-mail html is generated it, TRACKING will be replaced by
Important point is to return a response of type image and return a one pixel transparent image with REST response.
So i'll assume that the email contains a link to your Site. Certainly GA can record how often that link is clicked because clicking the link will open the page in turn causing the function *_trackPageview()* to be called, which is recorded by GA as a pageview.
So as long as that page has the standard GA page tag, no special configuration is required--either to the GA code in your web page markup or to the GA Browser. The only additional work you have to do is so that you can distinguish those page views from page views by visitors from another source.
To do that, you just need to tag this link. Unless you have your own system in place and it's working for you, i recommend using Google URL Builder to do this for you. Google URL Builder is just a web-form in which you enter descriptive terms for your marketing campaign: Campaign Source, Campaign Medium, Campaign Content, Campaign Name. Once you've entered values for each of these terms, as well as entered your Site's URL, Google will instantly generate a 'tagged link' for you (by concatenating the values to your Site's URL).
This URL generated by Google URL Builder is the link that would be placed in the text of your marketing email.