Thursday 29 December 2011

Gotomeeting php api(oauth) implementation

I had a lot of problems connecting to citrix and making the api work, here are some steps to take:

Oauth integration:

$key = '#';
$secret = '#';

$domain = $_SERVER['HTTP_HOST'];
$base = "/oauth/index.php";
$base_url = urlencode("http://$domain$base");

$OAuth_url = "https://api.citrixonline.com/oauth/authorize?client_id=$key&redirect_uri=$base_url";
$OAuth_exchange_keys_url = "http://api.citrixonline.com/oauth/access_token?grant_type=authorization_code&code={responseKey}&client_id=$key";


if($_SESSION['access_token']) CreateForm();else
if($_GET['send']) OAuth_Authentication($OAuth_url);
elseif($_GET['code']) OAuth_Exchanging_Response_Key($_GET['code'],$OAuth_exchange_keys_url);

function createForm(){
// you are loged in, play around
}


function OAuth_Exchanging_Response_Key($code,$url){
 if($_SESSION['access_token']){
  CreateForm();
  return true;
 }
 $data = getURL(str_replace('{responseKey}',$code,$url));
 
 if(IsJsonString($data)){
  $data = json_decode($data);
  $_SESSION['access_token'] = $data->access_token;
  CreateForm();
 }else{
  echo 'error';
 }
}

function OAuth_Authentication ($url){
 $_SESSION['access_token'] = false;
 header("Location: $url");
}



/*
 * CURL function to get url
 */
function getURL($url,$auth_token = false,$data=false){

 // Initialize session and set URL.
 $ch = curl_init();
 
 curl_setopt($ch, CURLOPT_URL, $url);
        // curl not working local machine, using fiddler
 curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');
 
 // Set so curl_exec returns the result instead of outputting it.
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 
 if($auth_token){
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: OAuth oauth_token='.$auth_token));
 }
 
 // Get the response and close the channel.
 $response = curl_exec($ch);
 
 /*
  * if redirect, redirect
  */
 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
                     if ($code == 301 || $code == 302) { 
                         preg_match('//(.*?)">/', $response, $matches); 
                         $newurl = str_replace('&','&',trim(array_pop($matches))); 
       $response = getURL($newurl);
                     } else { 
                         $code = 0; 
                     }
 curl_close($ch);
 return $response;
}

To start login you need to access ?send=1. I am using fidler as a proxy for https requests because my server is not set up for this.

Sunday 25 December 2011

JS OOP

If you thought that JS is written only using functions and objects, well, you are kind of wright :). But actually it is the most permissive (in my opinion) OOP language.
A class in js is defined using "function" and when we use something like:
function sum(a,b){
    return a+b;
}
we actually create a new class named "sum". All that we see inside the "{...}" is actually the constructor, so when we call
var c = sum(1,2)
c will be equal to 3, because that is what the constructor of the class returns, the sum of the variables.
If we would use
var c = new sum(1,2);
c would be an instance of the class sum. Of course for the purpose of simplicity class sum dose not have any variables or methods attached to it, so let's go ahead and make this a little more complex.
Let's define a new class that we can also use as a standalone function.

function Animal(name,species){
    // standard (for me) way to use default values for params
    // also the params will be private vars in our class
    name = name || "Unnamed";
    species = species || "Unknown";

    // setup some public vars
    this.animalTitle = name + ' the ' + species;

    // setup some private vars
    var age = 0;

    // create a private methos
    var grow = function(years){
        return age + years;
    }

    // some public methods(functions :) )
    this.getOlder = function(how_much){
        // here we access the private var
        // and a public one
        how_much = how_much || 0;
        age = grow(how_much);
        this.animalTitle = name + ' the ' + species + ' at ' + age + ' years old';
    }

    // using return to demonstrate how it works as a simple function
    return this.animalTitle;
}
Ok, now let's explain more.
name = name || 'Unnamed' is the same as if(name == null) name = 'Unnamed';. BTW, if you expect name, or whatever the param name will be, to be a bool or number you should use ==null or name = (name == null ? "Unnamed" || name) because 0 or false will make act in the expression used by me the same way as null.
this.animalTitle is a public variable that will be readable/writable, will see later.
age is a private variable that can only be used inside the class (also as I said in the inline comments, the params are also considered private vars).
grow is a private method, a function that can be called only inside the class definition.
And getOlder is a public method that can be called or overwritten.
Here is a example on how this can be used as a function:

var my_pet = Animal("Rex","Dog");
alert(my_pet);
// will alert "Rex the Dog"
or as a class definition to create an object:
var my_pet = new Animal("Simba","Lion");
alert(my_pet);
// will alert [object Object]
// to get a better understanding of what this is we can use GC console ot FF firebug and do:
console.log(my_pet)
alert(my_pet.animalTitle)
// will alert 'Simba the Lion'
my_pet.getOlder(10); // calling a public method
alert(my_pet.animalTitle)
// will alert 'Simba the Lion 10 years old'
my_pet.animalTitle = 'Custom title for my pet'; // overwriting a public member of the object
alert(my_pet.animalTitle)
// will alert 'Custom title for my pet'
Next we should talk about the prototype object.
Most of the js community talks about the prototype object as giving the functionability to add public methods/vars to classes. I actually don't like how this sounds and I will refraze it like this: "The prototype object is used to extend methods and variables of a class with the downside that you won't be able to use the private vars". Ok, now let's get back to some code:

// using our class Animal
Animal.prototype.whatToSay = 'I can say this:';
var my_pet = new Animal();
alert(my_pet.whatToSay);
// will alert 'I can say this:'

// we want to add a method named speak
Animal.prototype.speak = function(){
    // we can use public methods from our constructor and also ones we defined with prototype
    alert(this.whatToSay + ' My name is ' + this.animalTitle);
}
// we can't use age or grow() here because we don't have access to anything
// not defined in the constructor (function) with this. (public stuff)
var my_pet2 = new Animal();
my_pet2.speak();
// will alert 'I can say this: I am Unknown the Unnamed'
// why Unnamed? because we didn't gave him a name when we created him and this is the
// default string we gave it
var my_pet3 = new Animal('Bobo','Bear');
my_pet3.speak();
// will alert 'I can say this: I am Bobo the Bear'
Hope this will help somebody on a better understanding of the OOP in JS. Will continue with object members and inheritance.

Friday 9 December 2011

js async for, very cool

This is something nice. This code can create for interrupts for those long functions in ie, so you can tell the user what is happening :). You can run it in the fireBug's console to see what I mean :).


function async_for_each(object,cbk,limit_callback,end_cbk,limit,timeout,start){
    var l=object.length;
 limit = limit || Math.round(l/100);
 start = start || 0;
 timeout = timeout || 1;
 for(var i=start;ilimit){
   setTimeout(function(){
    async_for_each(object,cbk,limit_callback,end_cbk,limit,timeout,i)
   },timeout);
   limit_callback(i,l);
   return false;
  }else{
   cbk(i,object[i]);
  }
 }
 end_cbk?end_cbk():null;
 return true;
}

var a = [];
a.length = 1000;

async_for_each(a,function(){},function(i,l){console.log("locading %s/%s - %s%",i,l,Math.round(i*100/l))});

js extend method

this is what you need to use if you want to extend a function in js. Easy to use :).

// to use only for alert
Function.prototype.extend = function (fn) {
    var self = this;
 return function () {
  //console.log(self)
  //console.log(fn)
        try{
   var returnValue1 = self(arguments[0]);
   }catch(e){}
  try{
   var returnValue2 = fn(arguments[0]);
   }catch(e){}

        return returnValue1 && returnValue2;
    };
};

Some useful classes

Cookie class

function Coockie(){
 this.create = function(name,value,days) {
  days = days || 999999;
  if (days) {
   var date = new Date();
   date.setTime(date.getTime()+(days*24*60*60*1000));
   var expires = "; expires="+date.toGMTString();
  }
  else var expires = "";
  this.coockie_cache[name] = value;
  document.cookie = name+"="+value+expires+"; path=/";
 }

 this.read = function(name) {
  if(this.coockie_cache[name]) return this.coockie_cache[name];
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
   var c = ca[i];
   while (c.charAt(0)==' ') c = c.substring(1,c.length);
   if (c.indexOf(nameEQ) == 0) return this.coockie_cache[name] = c.substring(nameEQ.length,c.length);
  }
  return null;
 }

 this.eraseCookie = function(name) {
  createCookie(name,"",-1);
 }

 this.coockie_cache = {};
}
fireBug debug times class

var Debug = function(o){
 if('time' in console){
  if(Debug.times.length>0) console.timeEnd(Debug.times[Debug.times.length-1].name);
  Debug.times.push({name:o});
  console.time(o);
 }
}
Debug.times = [];
Debug.stop=function(){
 if('time' in console){
  for(var i=0;i< Debug.times.length-1;i++){
   Debug.times[i].total = console.timeEnd(Debug.times[i].name);
  }
  for(var i=0;i< Debug.times.length-1;i++){
   //log(Debug.times[i].name+": "+(Debug.times[i].total-Debug.times[i+1].total))
   //Debug.times[i].total = console.timeEnd(Debug.times[i].name);
  }
 }
};
js date week functions for date object

Date.prototype.getWeek = function () {  
    // Create a copy of this date object  
    var target  = new Date(this.valueOf());  
  
    // ISO week date weeks start on monday  
    // so correct the day number  
    var dayNr   = (this.getDay() + 6) % 7;  
  
    // ISO 8601 states that week 1 is the week  
    // with the first thursday of that year.  
    // Set the target date to the thursday in the target week  
    target.setDate(target.getDate() - dayNr + 3);  
  
    // Store the millisecond value of the target date  
    var firstThursday = target.valueOf();  
  
    // Set the target to the first thursday of the year  
    // First set the target to january first  
    target.setMonth(0, 1);  
    // Not a thursday? Correct the date to the next thursday  
    if (target.getDay() != 4) {  
        target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);  
    }  
  
    // The weeknumber is the number of weeks between the   
    // first thursday of the year and the thursday in the target week  
    return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000  
} 

Date.prototype.getWeekYear = function ()   
{  
    // Create a new date object for the thursday of this week  
    var target  = new Date(this.valueOf());  
    target.setDate(target.getDate() - ((this.getDay() + 6) % 7) + 3);  
    return target.getFullYear();  
}

Date.prototype.addDays = function(nr_of_days){
 var a = new Date(this.valueOf());;
 return nr_of_days==0?this:new Date(a.setDate(a.getDate()+nr_of_days));
}
Date.prototype.addDaysToSunday = function(){
 return this.addDays(
  7 - (this.getDay()==0?7:this.getDay())
 );
}
Date.prototype.moveToStartOfNextWeek = function(){
 return this.addDays(
  8 - (this.getDay()==0?7:this.getDay())
 );
}
Date.prototype.addWeeks = function(weeks){
 if(weeks<1) return this;
 return this.addDays(
  8 - (this.getDay()==0?7:this.getDay()) + 7*(weeks-1)
 );
}
Date.prototype.getISODay = function(){
 // Native JS method - Sunday is 0, monday is 1 etc.
 var d = this.getDay();
 // Return d if not sunday; otherwise return 7
 return d ? d : 7;
};

Date.prototype.getMaxWeekOfYear = function (){
 var year = this.getFullYear();
 var maxWeek = 52;
 fj = new Date(year, 0, 1); //1st Jan
 tfd = new Date(year, 11, 31); //31st Dec
 if(fj.getDay() == 4 || tfd.getDay() == 4){
  maxWeek = 53;
 }
 return maxWeek;
}