Wednesday, July 11, 2012

A JavaScript Instrumentation Technique for Easier Script Debugging


There are many ways to debug your JavaScript code. My favorite way is to use console.log() to dump variables and print program state to the debugging console.

The problem? 


If you've ever created a relatively large JavaScript library or program, specifically with lots of functions, your debugging log can quickly become overwhelming. At work, I ended up creating a decent size JS library. I found that every time I had to debug a problem, I was spending most of my time parsing my own debug statements than I was fixing the problem.

My Solution: Instrumentation!


Instrumentation can mean many things, so specifically I'm referring to tracing the execution flow of your scripts through logging. Take the following JavaScript as an example:

function addRand()
{
    var r = Math.floor(Math.random()*11); // return randomly between 0 and 10
    console.log("addRand returning: ", r);
    return r;
}

function mult(a, b)
{
    var m = a * b;
    return m;
}

function doStuff()
{
    var a=2, b=5;
    console.log("Multiplying A and B");
    var m = mult(a, b);
    console.log("Adding a random number to the result");
    m += addRand();        
    console.log("Result: ", m);
}

doStuff();

This code will produce the following (boring) log file:

Multiplying A and B
Adding a random number to the result
addRand returning: 2
Result: 12

Pretty sad, really. Firefox, Chrome, Safari, heck even Internet Explorer have now mostly adopted the Firebug way of debugging javascript. We can add a lot to our debugging by simply using two built-in functions, console.group() and console.groupEnd(). All they do is create (and remove) an indentation for any print statements between calls to each function. Together, they end up producing a very readable log. Here's the code with my Instrumentation added:

function _Instrument(info)
{
    console.group(
        info.name + " variables: ", (info.variables ? info.variables : "(void)")
    );
}

function _InstrumentEnd(info)
{
    console.log("Returning: ", (info && info.return ? info.return : "(void)"));
    console.groupEnd();
}

function addRand()
{
    _Instrument({name:"addRand"})
    var r = Math.floor(Math.random()*11); // return randomly between 0 and 10
    _InstrumentEnd({return: {randomNum: r}});
    return r;
}

function mult(a, b)
{
    _Instrument({name:"mult", variables: {a:a, b:b}});
    var m = a * b;
   _InstrumentEnd({return: {m: m}});
    return m;
}

function doStuff()
{
    _Instrument({name: "doStuff"});
    var a=2, b=5;
    console.log("Multiplying A and B");
    var m = mult(a, b);
    console.log("Adding a random number to the result");
    m += addRand();        
    console.log("Result: ", m);
    _InstrumentEnd();
}

doStuff();

Sure, it may add a couple lines of code to each function, but it results in a log file with much more information. Put this into an environment with thousands of lines of debug information, and it becomes significantly more readable, and faster to parse.


By printing to your log when you enter and exit each function, you can quickly pinpoint which function is responsible for errors. This method also helps you trace the execution path of your scripts, which can help reduce your time spent on debugging. This has reduced my debugging time, and made it a lot less annoying to parse my logs, double win!

If you're interested in what other functions you may be able to use to enhance your debugging logs, check out Firebug's Logging API, as most of these functions are built-in to Firefox and Chrome.

Saturday, July 7, 2012

A Basic Guide for Newbie Yii Developers Part II


This is Part II of my introduction to Yii tutorials. If you haven't yet, take a look at Basic Guide for Newbie Yii Developers Part I.

Last week I covered how to create your first Yii project and put it under version control. In that tutorial, we created the project files for our first app: Yiicommerce. If you have been following along, great! If not, you can find the project files on Github. I have made a Git Tag representing the state of the project at the end of the last tutorial (don't worry, I'll show you how to do it too!), so download Tutorial-Part.I and follow along!

If you're using Git, you can also checkout the tag like this:

$ git clone git@github.com:brixican/Yii-commerce.git
$ git checkout tutorial-part.I

In part II of this series, we will begin designing our e-commerce application, starting at the database level. Today we'll build our database schema in MySQL, and use Yii's built-in Gii component to generate our initial Models, Views and Controllers. Before we get started, I think a brief introduction into some core Yii elements are in order.

An Overview of the Yii Framework

Models, Views, Controllers, Oh My!

If you have already begun looking into using Yii, or any PHP framework, no doubt you've been barraged by the term MVC. What is MVC? It's a design pattern. It's a best practice, if you will, for organizing your code and functionality. By separating core components of your application, such as the business logic, user interfaces, and the data, you (the developer) can focus on developing each component without worrying about breaking, or interfering with, the others. If you are absolutely new to the MVC design pattern, I would highly recommend taking a quick look at the official Yii MVC Fundamentals tutorial, as they do a great job at explaining what MVC is and how it works. I will assume you have a basic grasp of the concept. Rather than explain MVC, I will explain where various portions of a website fit into these designs.


Models

Models are the core of your application. They contain your business logic. They also dictate how data is accessed and stored. Models can hold any and all information in a website. For Pieces of Eight Costumes, models are used to represent each individual product in the site. My models store price information, product names and descriptions. They also store relational data, such as what sizes (small, medium, large, etc..) each product supports, the category a product falls under, and other important relations. Of course the models I am describing here store data in a database, but Yii also supports other types of models as well. Not all data handled by a website gets stored into a database. For example, a "Contact Us" form, that takes some user input and emails it somewhere does not necessarily need to store that information. Yii provides us with special models designed to temporarily store this data. It helps us organize, manipulate, and validate our input before deciding to either store it, email it, or display it.


Views

Views contain all of the logic to present your website to your audience. Not only will views be where you write your HTML, they will also be where you invoke CSS and Javascript, perform AJAX calls, render web forms, and create templates and layouts. Views also aid in gathering user input and passing it into a Model. For example, a contact form stores its data into a model, but gets passed into a view to be rendered. The same form can be rendered in a variety of ways simply using different views. In general you will have a view per section of your website, such as a "Contact Us" view, "About Us" view, a view for your home page. However many views are also very re-useable. For example for PiecesOfEightCostumes.com, each category uses the same view to render the data, we simply pass it different products to render. Also, the page to render a single product is a generic view that simply takes a Product model and renders it to the page. In Yii, views come with many very handy functions to help speed up the development of HTML.


Controllers

Controllers are essentially the glue of any application. They control the flow of the users experience: handing them to the different views on your website, passing data between views and models, and helping to select which business logic to invoke based on the current state of the application. Controllers are comprised of Actions. In the 'Contact Us' example, our action would instantiate and initialize our ContactForm model and pass it to the Contact view. Yii also maps actions to URLs, so we could setup a url such as www.website.com/contact to begin the process of rendering the view.


Yii Folder Structure

Right now, the folder structure for Yii-Commerce looks like this:
  • yiicommerce/
    • assets/
    • css/
    • images/
    • protected/
    • themes/
    • index-test.php
    • index.php
    • README.md
We'll eventually explain the purpose of most of the files, but in this tutorial we are going to focus on the contents of protected/, as that is where the majority of the Yii-Commerce project files are:
  • yiicommerce/protected/
    • commands/
    • components/
    • config/
    • controllers/
    • data/
    • extension/
    • messages/
    • migrations/
    • models/
    • runtime/
    • tests/
    • views/
    • .htaccess
The amount of folders may seem a bit overwhelming at first, but don't worry! They are purely for organizational purposes. For example, all of our application's Models will be placed in the models/ directory. If you begin exploring these folders, you'll see our application already has some models an controllers and such. That's because the app we generated is already functional! We'll be deleting and editing files we don't need, so for now you can ignore the additional functionality in the application.

Designing our Database Schema

Finally we get to the coding! In my opinion, the best place to start designing an application for Yii is with the database. Being an e-commerce application, our number one concern is selling products. We need a way to represent a product in our database. Let's start off by making Products and Categories. We want products that have a name, price, and description. Each Product will belong to exactly one Category, and each Category can contain multiple products.

In your protected/data/ folder, create a file called yiicommerce.schema.sql with the following contents:

#-- Category : represents a Category in the database
#-- Category HasMany Product
CREATE TABLE yc_category
(
 #-- Key
 id  INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
 #-- Attributes
 name  VARCHAR(255) NOT NULL,
 
 #-- Constraints
 PRIMARY KEY (id),
 UNIQUE KEY fk_category_name(name)
 
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


#-- Product : a product to sell in our application
#-- Product BelongsTo Category
CREATE TABLE yc_product
(
    #-- Key
    id            INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

    #-- Attributes
    name          VARCHAR(40) NOT NULL,
    price         DECIMAL(6, 2) NOT NULL,
    description   TEXT,
    
    #-- Relationships
    category_id   INTEGER UNSIGNED NOT NULL,

    #-- Constraints
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES yc_category(id),
    UNIQUE KEY uk_product_name (name)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

#--
#-- Test Data
#--
INSERT INTO category (name)
VALUES
 ("Electronics"),
 ("Clothes"),
 ("Sporting Goods");

INSERT INTO yc_product (id, name, price, description, category_id)
VALUES
 (1, "Laptop", 1200.00, "A stunning little laptop.", 1),
 (2, "Smartphone", 299.99, "The most powerful smartphone yet.", 1),
 (3, "White Shirt", 12.50, "Comfortable, cotton, and plain.", 2),
 (4, "Football Helmet", 68.75, "Authentic NFL helmet.", 3);
Here, we have created the schema for our products. A product has Name, Price, and Description attributes. It uses an integer as the Primary Key inside of the database, and as a further constraint, no two products can have the same name. We also link Products and Categories together using the category_id attribute. By linking in this way, our Category models can each contain many Products, but our Product models can only belong to exactly one Category. We also created a few test categories and products, which we can always alter later.


Now that we've created the schema, it's time to make our tables. If you're using XAMPP or something similar, you probably already have phpMyAdmin installed. Go to http://localhost/phpmyadmin, and create a new database called yiicommerce. Once created, click the SQL tab, then copy and paste the contents of your schema file and hit the Go button. You will now see two tables, yc_category and yc_product.


Now we need to configure Yii to communicate with our database. Open the config file located at: /protected/config/main.php. Locate the 'components' key, and under that the 'db' key. You'll notice there are two entries, an sqlite string and a commented-out mysql string. Since we're not using sqlite, delete that one and uncomment the mysql string. In the 'connectionString', replace 'mysql:host=localhost;dbname=testdrive' with 'mysql:host=localhost;dbname=yiicommerce', and fill in your username and password to your database if necessary. Yii now has access to our database. 


Gii 

We're going to use Yii's built-in component called "Gii" to take our database schema, and generate our models, views, and controllers for us. While this is not a feature unique to Yii (Ruby on Rails, Symfony, CakePHP, etc.. all have a similar tool), it is nevertheless a very powerful tool that Yii provides us. 

In the config file, scroll up to the 'modules' key, and uncomment the Gii tool, as we will be using this next. Change the password to something simple, and remember to remove this section before ever deploying your Yii application.


Visit the following URL to login to the Gii tool (using the password in your config file): http://localhost/yiicommerce/index.php?r=gii, then click on the 'Model Generator' link. 


For the Table Prefix, put in the 'yc_' prefix that we added to all of our table names. Insert '*' under Table Name to have Gii generate all of our tables at once. Finally, click the preview button, and then the generate button. If Yii has an error writing the files, make sure your directories are writeable using the following chmod command:


$ chmod -R 766 protected/


Now that Yii has now created our models, let's make a controller and a view for it. Click the 'Controller Generator' link, and enter 'product' for the controller id field. We'll leave the Action IDs with just index for now. Again, click preview and generate to create our controller and view file. 


We now have the following files created in our protected/ folder:

  • models/Product.php
  • models/Category.php
  • controllers/ProductController.php
  • views/product/index.php
We can view our newly created content (although there's not much to see) by going to the following URL: http://localhost/yiicommerce/index.php?r=product


Committing our Changes

Now that we have altered our application, it's time to save our changes. The following Git commands will add our files into our repository, and commit changes to existing files:
$ git add -A
$ git commit -a -m "Added Product and Category models. Created controller and view for Products"
$ git push origin master
After entering your password, your changes will now be commited into your github repository. You'll notice I've been creating Tags for each tutorial. A Tag is essentially a snapshot of the project files. To create the Tag for this tutorial, I ran the following commands:
$ git tag -a tutorial-part.II -m "Tutorial Part II"
$ git push --tags origin master
While tags are not something you will create often, they work very well for tagging release versions of software.


Anyway, that's it for today! Next time we'll spruce up those controllers and views and start making some useful web functionality!



Wednesday, July 4, 2012

Me want website, but where to start? A basic guide for newbie Yii Developers - Part I

Welcome to my Yii developer tutorial series! These tutorials are aimed at taking absolutely new Yii developers through the process of developing their first website. Instead of creating a boring Blog application, I am going to walk through the process of creating a (very basic) E-Commerce site. I'll go into more details about what we will be building in the next post. In the first installment of my set of Yii tutorials, I'm going to show how to:
  • Download and test Yii
  • Creating our first project
  • Git-ing started with version control
First, an introduction is in order. Who the hell am I, and where do I get off teaching you how to code? My name is AJ Perez. I do computer security for a living and web / game development as a hobby. I have been using Yii for the past couple of years and have been developing with PHP ever since I started programming. I received my degree in Computer Science from Oregon State University in 2010. I tend to dabble in many things, and always have multiple projects going on outside of work, but web development is still my favorite hobby.

Whew, got that out of the way. My goal here is to get new developers moving in the right direction. I don't claim that what I will show you, nor how I develop it, are necessarily the best practices for Yii. If it gets you hitting the ground running and producing results than I will consider my job done.


Disclaimer: if you are new to Yii and reading this, I am just as new to writing tutorials as you are to the framework, so positive (and negative!) feedback is welcomed and encouraged. 


These posts will be an ongoing set of tutorials, building upon the same project throughout each tutorial until we end up with a basic, but finished, website. Due to content length, I may end up splitting some tutorials amongst multiple posts, but I'll be sure to link them appropriately. I will also have my version of the code on github, so people can download it and see the code first hand, but I encourage people to do these tutorials alongside me, as nothing beats learning by doing it yourself. Finally, enough blabbing, let's get started shall we?

Downloading Yii

If you haven't already, go ahead and Download Yii from their website. At the time of this writing, Yii 1.1.10 is the latest version so that is what I will be using. Once downloaded, unzip the folder from the archive and place it into your webroot (I renamed the folder from the default yii-1.1.10.r3566 to simply "yii". I'll assume you already have a local development environment established (but if not, I would recommend XAMPP for OSX or Windows). I use OSX for my web development, so my tutorials will be done in that environment, but absolutely all of the tasks I do will carry over to a Windows (and especially Linux) environment, albeit a few minor differences at times.


The folder we now have contains the following folder structure:

  • demos/
  • framework/
  • requirements/

We'll leave the demos folder for now, since they can be useful in seeing various ways to build projects. In your web browser, visit the following url: "http://localhost/yii/requirements/"

Before moving on, fix any errors marked as "Failure". If your tests look similar to mine then you have successfully installed Yii, congratulations!

The First Project

Alright, we finally gave our Yii framework a nice little home in our webroot, now it's time to setup the project files for our first Yii application. We're going to use Yii's built-in "YiiC" app to auto-generate our project files for us. I decided to name our application "YiiCommerce," I know, I'm so creative. The following process is highly documented, so if you get lost following me, try Yii's documentation for Creating your First Yii Application

1) In a command-line terminal, navigate to your webroot:

$ cd /Applications/XAMPP/htdocs/

2) We should now see our "yii/" folder. Run the following command to generate our project files:
$ php yii/framework/yiic.php webapp yiicommerce

* If your console complains about not being able to find your php executable, just use the full path instead:
/usr/bin/php in Linux, 
/Applications/XAMPP/xamppfiles/bin/php in OSX

3) We should now see the following folders in our webroot:
  • yii/
  • yiicommerce/

To test it out, visit the following URL: http://localhost/yiicommerce/index.php
If you see a welcome message, then congratulations, we have our first Yii application running! We'll start the process of making it all fancy in the next tutorial.

Git-R-Done!

Setting up our Git Repository

Now that we have our project files ready, it's time to add them into a Git Repo. If you're new to Git, I'll attempt to explain the Git commands as I use them. There's a great Git Tutorial here that I often refer back to, if I forget a particular command. I'm not going to attempt to walk you through the process of installing and setting up Git, since their creators did such a good job walking you through the process already. So, follow their Github guide to set it up.


Once Git is installed and configured, we can create our repository. Create a new public repository (on github), I called mine "Yii-Commerce," and you can view it here. Since we're using github, you'll notice a button that's called "Gitignore", scroll down its list and click 'Yii'.  Github is nice enough to have bunches of presets for many types of projects that will automatically ignore files that shouldn't be included in your repository. In case you didn't see it, don't worry, i'll walk through the process of setting up our .gitignore file later.


Now that you have your repository, we need to add our project files to it! In your command line, change the working directory to your newly-created project:


$ cd webroot/yiicommerce/


Now run the following command to create and initialize an empty local repository:


$ git init


Next, add all of the files from your project into the Git repo:


$ git add .
$ git commit -m "First Commit"


Here, we have added all of the files from our project into our Git repository. Committing the changes to the repo finalize the adding process. Git will make sure you always add a message for each commit, so make sure you choose meaningful messages such as: "Edited the product model - now includes pricing and descriptions for each model." Meaningful messages will help you track your changes more accurately.


The next step is to push our local repository to github. On your github page, you should see your .git url, mine is:


https://github.com/brixican/Yii-commerce.git


This is the address to your remote repository on github. To connect it to our local repo, use the following command:


$ git remote add origin https://github.com/brixican/Yii-commerce.git


Replacing my URL for yours, of course. Lastly, we can push our local repository over to our remote one:


$ git pull origin master
$ git push origin master
If your Git installation was anything like mine, it complained about SSH keys! If it worked, you can skip these steps.


To setup your SSH Keys, follow Git's generating ssh keys tutorial. If this doesn't work (again, like my git installation), then we'll switch from using the HTTPS git server to the SSH-based one. Run the following two commands to switch your repo:
$ git remote rm origin
$ git remote add origin git@github.com:brixican/Yii-commerce.git
Now we should be good to go, we'll try to merge and push our repos again:


$ git pull origin master
$ git push origin master


...and it finally worked! Hopefully you won't have as many problems as I had setting up a git repo, but if you did hopefully my suggestions helped you get it going. You can verify that the repository has been uploaded successfully by refreshing your project page on github. If you can see your project files, then all is well. Now we finally have our first Yii project safely saved into Git. 


Keep an eye posted for my next post, where we'll start adding some of our business logic into our application. Finally, some real coding! If I have any errors, or you have any problems or suggestions, let us hear about them in the comments!


See you next week!


Edit: Part II of this series is now up!

Wednesday, June 13, 2012

Yii Development Tutorials

Well, it's been a while since I have written any blogs. Development on Fireteams has stopped for the time being as well. Unfortunately I have just had too many things happening at once.  On the plus side, I just finished an e-commerce website for a client (check it out! Pieces of Eight Costumes). I used Yii to make this website for them, and I'll be posting some tutorials about how to use Yii to implement various parts of an e-commerce site! Here's a look at what to expect in the coming months (not necessarily in this order):
  • Me want website, but where to start? A basic guide for newbie Yii developers
  • So I heard you like E-commerce.. (How to start developing your e-commerce site using Yii)
  • Developing a basic cart with PayPal integration with Yii
  • Creating a complex AJAX form with Yii and JQuery
  • Yii + Google ==  — Good SEO practices for any website
  • How to deploy a Yii website on HostGator
  • My favorite Yii / JQuery plugins of 2012
There'll be additional tutorials as well, but I will most definitely be writing these articles in the months ahead. Hopefully developers still rather new to Yii will find these tutorials useful and get a good feel for how powerful the framework is. 

If you have any tutorial requests, or would like to share links to other great tutorials out there, let us know in the comments!