Why you shouldn’t interrupt a programmer

Posted on October 28th, 2013 by Damien Filiatrault

This is so true; humans have RAM. If we don’t respond immediately, we’re likely doing something along these lines.

http://heeris.id.au/2013/this-is-why-you-shouldnt-interrupt-a-programmer

Posted in Uncategorized | No Comments

We are headed to Medellín!

Posted on September 20th, 2013 by Damien Filiatrault

Scalable Path is now a Silver Sponsor of JSConf Colombia, taking place October 18th and 19th in Medellín, Colombia. We’re excited to learn from the speakers, meet the talented Javascript development community and explore the beautiful area of Antioquia.

Posted in Javascript, Marketing | No Comments

See you at Symfony Live San Francisco!

Posted on September 20th, 2012 by Michelle Ryan

Symfony Live San Francisco is just around the corner. We’re proud to be a Silver Sponsor and are excited for the opportunity to:

• meet the Symfony community
• talk with the Symfony core team
• share our experience with the framework
• meet Drupal members and learn about how Drupal met Symfony

 

 

 

It will be a thrilling time indeed! We even got these cool new t-shirts printed just for the occasion!

Scalable Path T-shirt

The Symfony community is leading the charge to bring cutting edge practices to the PHP world and we’re stoked to be a part of it. If you’re planning on going, make sure to find us and say hello!

Posted in Marketing, symfony | No Comments

Facebook Connect with Symfony 1.x

Posted on June 21st, 2012 by Marc St Raymond

This is a post for anyone interested in implementing Facebook Connect on a Symfony 1.x project. There are of course many ways to do this…but here are some of the driving factors behind the approach we describe below:

  • We wanted to leverage Facebook to handle authentication, provide a seamless sign up experience, and allow us to use social features
  • We wanted some control over the session – meaning once a user was authenticated we wanted to operate independently of whether or not she remained logged into Facebook
  • Along those same lines, we wanted to set our own “remember me” cookie to identify returning users as opposed to relying on the Facebook session
  • We wanted to be able to drop users back on the page from which they logged in, which meant refreshing the page upon login to update user-specific content
  • We wanted to grab fresh authentication tokens whenever possible, but do not use them very much at the moment. Since we’ve allowed the scenario of someone being logged into our site without an active Facebook session, the case could arise that we have a logged in user but no access to her current Facebook data. The simple solution is to ask the user to log into Facebook at the point when that information is needed.
  • And lastly, we are using the sfGuard plugin for handling users

So let’s get down to it…here’s what we did:

1) Load the Facebook Javascript SDK in the layout, just after the body tag. This makes sure it gets loaded on every page at the right time.

//in apps/frontend/templates/layout.php

<body>
<!-- START FACEBOOK JAVASCRIPT SDK -->
<div id="fb-root"></div>
<script>
 window.fbAsyncInit = function() {
  FB.init({
  appId        : <?php echo sfConfig::get('app_facebook_app_id') ?>, // stored in app.yml for convenience
  //channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File (we haven't implemented this yet, so we just comment it out)
  status       : false, // check login status (we don't make use of this)
  cookie       : true, // enable cookies to allow the server to access the session
  xfbml        : true  // parse XFBML
  });
 };

 // Load the SDK Asynchronously
 (function(d){
  var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
  if (d.getElementById(id)) {return;}
  js = d.createElement('script'); js.id = id; js.async = true;
  js.src = "//connect.facebook.net/en_US/all.js";
  ref.parentNode.insertBefore(js, ref);
 }(document));
</script>
<!-- END FACEBOOK JAVASCRIPT SDK -->

<div id="main">
// Page content

2) Attach Facebook’s login method to our custom sign up/log in button. In the callback function, if the user is successfully authenticated, make an AJAX call to an action that will handle the user data, then reload the page. To ensure the action gets completed before the page reload, we made the AJAX call synchronous. (UPDATE: Thought of a better way to handle the page reload…simply execute in the ‘complete’ callback function of the AJAX call) This approach was driven by the fact that we wanted to drop users back onto the page that they were already on. If you have a destination page where users are sent upon login, then this doesn’t need to be done in AJAX…the code for handling the Facebook data could be put into the action for that landing page.

//in web/js/scripts.js
//Feel free to attach this function to your login button however you'd like

//Function gets executed when the login button in the header is clicked
function onClickloginfb() {
   //Use the FB object's login method from the Facebook Javascript SDK to authenticate the user
   //If the user has already approved your app, she is simply logged in
   //If not, the app authentication dialog box is shown
   FB.login(function(response) {

      //If the user is succesfully authenticated, we execute some code to handle the freshly
      //logged in user, if not, we do nothing
      if (response.authResponse) {               

         //Use ajax to execute an action that handles authenticated user
         $.ajax({
            url: "/facebook-connect-login",
            complete: function(){
               //Reload the page after the user is authenticated to update user-specific elements
               window.location.reload();
            }
         });
      }
   }, {scope:'email'});  //we just ask for the email permission
}

3) The new action that handles the Facebook data makes use of Facebook’s PHP SDK…we use some custom code that makes a call to Facebook’s graph API to grab the user’s info…but this could be done via functions in the SDK as well. If the user is not in our database, then a new user is created and populated with data (we created a function in the sfGuardUser model class to handle this). If the user IS in the database already, we simply grab a fresh profile picture, and grab a fresh Access Token from Facebook.

//in apps/frontend/modules/user/actions/actions.class.php
//The action executed via ajax after the facebook authentication (/facebook-connect-login)
//This is where the real magic happens

public function executeFacebookConnectLogin(sfWebRequest $request)
{
 //Creating a new Facebook object from the Facebook PHP SDK
 require_once sfConfig::get('sf_lib_dir').'/vendor/facebook-php-sdk/src/facebook.php';

 $facebook = new Facebook(array(
  'appId'  => sfConfig::get('app_facebook_app_id'),
  'secret' => sfConfig::get('app_facebook_secret'),
 ));

 //Get user object from Facebook - this method is only executed after we've confirmed that the user
 //has an active session with facebook and that our app is approved...so it should work
 $facebook_user = $facebook->getUser();

 if ($facebook_user)
 {
  try
  {
   // Proceed knowing you have a logged in user who's authenticated through facebook
   $access_token = $facebook->getAccessToken();

   //Grab the user's data from the facebook graph API using the fresh access token
   //we define which fields we want in app.yml ("id,first_name,last_name,picture,email,gender,friends")
   $requestUrl = 'https://graph.facebook.com/me?access_token='
       .$access_token
       .'&fields='.sfConfig::get('app_facebook_fields');  

   $response = @file_get_contents($requestUrl);

   //TODO: Down the road, try new method of getting info here:
   //http://developers.facebook.com/docs/reference/php/facebook-api/
   //$facebook_user_profile = $facebook->api('/me');      

   if($response)
   {
    $facebook_user_profile = json_decode($response);

    if(!is_null($facebook_user_profile->email)) //just to make sure we have the right data
    {
     //Check to see if user is already in our database
     $user = Doctrine::getTable('sfGuardUser')->getUserByFacebookId($facebook_user_profile->id);

     //If no, create a new user instance and populate with data from facebook
     if(!$user)
     {
      $user = new sfGuardUser();

      //This function saves the user's first name, last name, gender, email address,
      //picture, and Facebook id
      $user->getUserDataFromFacebook($facebook_user_profile);

      //Save the fresh access token to the DB for later use
      $user->setFbAccessToken($access_token);

      //Save new user data to database
      $user->save();

     }else
     {
      //If user IS already in the database, just refresh the profile picture
      //and access token.

      $user->setProfilePicture($facebook_user_profile->picture);
      $user->setFbAccessToken($access_token);
      $user->save();
     }

     //Finally, log the user in using sfGuard method
     if($user)
     {
      if (!$this->getUser()->isAuthenticated())
      {
       //Second parameter activates the remember me cookie when set to true
       $this->getUser()->signIn($user, true);
      }
     }
    }
   }
  }
  catch (FacebookApiException $e)
  {
       error_log($e);
       $facebook_user = null;
  }
 }

 //This is all done via AJAX, so no html is rendered
 return sfView::NONE;
}

4) The method we add to the sfGuardUser model for saving the data from Facebook is very straightforward.

//in lib/model/doctrine/sfGuardUser.class.php
//the sfGuardUser method to save the data from facebook

public function getUserDataFromFacebook($facebook_user_profile)
{
    $this->setFirstName($facebook_user_profile->first_name);

    $this->setLastName($facebook_user_profile->last_name);

    $this->setEmailAddress($facebook_user_profile->email);

    //These last three fields are actually in the sfGuardUserProfile table, but we made proxy
    //methods in the sfGuardUser object for convenience

    $this->setFacebookId($facebook_user_profile->id);

    $this->setGender($facebook_user_profile->gender);

    $this->setProfilePicture($facebook_user_profile->picture);
}

Some Closing Thoughts:

As of right now, we are not doing anything else outside of authentication and the initial grab of user data that makes use of the Access Token. We store the freshest one in the database and at some point we may use it to do things like hit the graph API to record when users take certain actions that we want to display on their timelines.

Once the user is authenticated through Facebook, we simply use sfGuard’s standard signin function with the rememberme option set to TRUE. This sets the rememberme cookie in their browser (defaults to 15 day lifetime), and we have activated the rememberme filter in the frontend app to check for this when a user first hits the site. This means that once the user is signed in, we are completely independent from her Facebook session (i.e. she could log out of Facebook in another tab and still be logged into our website)…when the time comes that we start to use the Access Token this will (rarely) present an issue, but we will simply ask users to sign in again if they want to perform an action that requires us to have a valid Access Token.

Thoughts? Suggestions? Feedback? Let us know what you think in the comments – we’d love to hear how this works for others and if there are ways to improve it!

Posted in symfony | 2 Comments

What’s all this talk about Responsive Web Design?

Posted on June 5th, 2012 by Michelle Ryan

How do you view content on the internet? On your computer? Mobile? Tablet? TV?

If you answered yes to most or all of the above, you’re in good company. In the near future we will most likely only be adding to this list. Video game consoles, for example, now have web browsers. But this presents a challenge. How do you serve up a site on all these different screen sizes and input methods, not to mention the continued nuisance of multiple browsers?

Current solutions for smartphones include scaling down the size to fit or building a separate mobile version of a site. Scaling down can make content difficult to read and a site hard to interact with. Creating a separate mobile version is cumbersome leaving developers responsible for managing the code for multiple code bases. And that only addresses the mobile issue.

So what is the answer? Do we continue to develop multiple versions of the same site with every new device that emerges? This solution is not only unrealistic, but causes a single web site to suffer from a sort of multiple personality with disconnected designs and content across the multiple devices. Instead, why not leave users with the same experience no matter where they view a site?

Responsive design, we welcome you! With the responsive method of designing and developing, a site will fluidly adapt to fit all screen sizes, from the widest displays to mobile phones. Technically, responsive design is achieved through fluid grids, flexible images, and media queries. From a design perspective, it demands that we think differently. Rather than creating device specific layouts, we must design a single layout that adapts to multiple devices.

Responsive design isn’t the solution for all cases. There are times when the mobile version of a site should be different. But as the inventor of responsive design, Ethan Marcotte, said, it does allow us to “design for the ebb and flow of things.”

Want to learn more? Check out these great resources:
unstoppablerobotninja.com
teamtreehouse.com
webdesign.tutsplus.com
blog.responsivenews.co.uk

And finally, there’s a growing number of responsive sites out there. Below you’ll find a handful of well designed examples. If you’ve developed a responsive site let us know. We’d love to check it out!

Posted in Design | No Comments

The Future of Data Stores and NewSQL

Posted on May 17th, 2012 by Damien Filiatrault

I just read a good article the 451 Group entitled NoSQL, NewSQL and Beyond: The answer to SPRAINed relational databases.  It’s a good summary of the current, fast-evolving database landscape.  I especially appreciated the Venn diagram shown here.

As someone who has done mostly relational database programming in MySQL, I found myself tempted to use MongoDB and other NoSQL solutions simply for their scalability, which I think now is the wrong way of thinking about it.  If the NewSQL options can give us the familiarity and functionality of SQL-based relational databases AND the scalability of the new NoSQL DBs, that will be a will great option for many of us in the PHP world.

Posted in Uncategorized | No Comments

Light Table IDE Kickstarter Project

Posted on April 27th, 2012 by Damien Filiatrault

A friend just shared a link to the Kickstarter project for Light Table, an IDE that (if funded) will try to make our lives better as programmers. I have a lot of respect for people who can think outside the box like this guy David Granger who is heading the project. He worked on Visual Studio at Microsoft so he appears to have solid experience in the area. I also really like that the first language supported will be Javascript. JS is where the real action is in the web dev world right now with frameworks like Backbone and Meteor coming up.

Posted in Uncategorized | 1 Comment

Why Backbone.js is awesome

Posted on April 14th, 2012 by Damien Filiatrault

Backbone.js

I started hearing about Backbone from some fellow developer friends recently. They all had good things to say about it so I decided to check it out. The first paragraph on their website is a bit dense, even for a computer science major:

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions,views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

After spending some time playing around with Backbone, perhaps a more user friendly opening paragraph would be:

Backbone is a framework that speeds development and keeps your code organized just like a server-side framework like Symfony or Rails.

A company called DocumentCloud created Backbone for their own project(s) and has open-sourced it to the world.  Thank you, DocumentCloud.

A couple of years ago, I realized that everyone was implementing Javascript in their own, different way and that managing JS on a project with multiple developers quickly became a mess.  I implemented a standard Object-Oriented Javascript approach with my team to try to get developers writing code in the same way so that code could be understandable by other people and reusable between projects.  The only requirement for this original approach was jQuery, and it allowed for certain things like class inheritance.

However, when I started working with Backbone, I realized that it could completely replace the system I had been encouraging my team to use.  Backbone requires jQuery and Underscore (another useful JS library by DocumentCloud), and it provides a TON of features:

  • Models
  • Collections
  • Views
  • Routing
  • Events
  • History
  • Syncing with a RESTful web service

We’ve immediately begun using Backbone on both internal and client projects and are encouraging all developers at Scalable Path to get familiar with it.  Building the next generation of highly responsive web applications will require the tools that Backbone provides.

Posted in Uncategorized | No Comments

What did the Apple website look like in 1996?

Posted on March 27th, 2012 by Michelle Ryan

Since Apple has been a major influencer in web design for years, looking back at the early days of Apple.com may be a shocker. The King of Minimalist Design that is mimicked by designers everywhere has definitely come a long way. We put together this quickie video so you can see Apple’s evolution from 1996 to now.

Thanks to Wayback Machine for making the screenshots available. What company’s web interface evolution would you like to see next?

Posted in Uncategorized | No Comments

Web Development for the iPad and iPhone

Posted on April 7th, 2011 by Damien Filiatrault

I just read this extremely well-thought-out article on designing and developing web-based applications for the iPhone and iPad. It talks about the pros and cons of web-based vs. native apps and actually came up with some reasons for going web-based that I hadn’t thought of.

http://www.smashingmagazine.com/2010/05/28/web-development-for-the-iphone-and-ipad-getting-started/

One of the highlights of the article is PhoneGap, which compiles your web-based app (written in HTML, CSS and JS) into native apps for all of the major phone operating systems. I am excited to play with it!

http://www.phonegap.com/

Posted in Uncategorized | No Comments