Official website for Web Designer - defining the internet through beautiful design
FOLLOW US ON:
Author: Steve Jenkins
11th February 2013

Laravel: A modern PHP framework

PHP has been crying out for a contemporary framework. Find out why Laravel is taking the community by storm

Laravel: A modern PHP framework

It’s difficult to deny the fact that, in recent years, the web development community has been incredibly hard on the PHP language and its faithful devotees. It’s no wonder why; at the time, a number of poignant PHP-hate articles began circling the web like a virus, and some of its flagship frameworks, such as CodeIgniter, were quickly growing stale. All the while, Ruby on Rails seemed to be leading the pack, in terms of innovation and ease of development. As time moved on, more and more coders found themselves ignoring PHP, as they instead reached for their Ruby toolbelts.

But things change; they always do. Along came a ridiculously smart young former .NET developer, Taylor Otwell, who was on the verge of unleashing a modern, elegant framework called Laravel, into the universe. At first, as is typically the case when yet another framework pokes its head up to say hi, many developers dismissed it as nothing but one more Sinatra clone that would quickly diminish into nothingness. But still, week after week, social network feeds were all of a flutter, praising Laravel’s elegance and readability. Could it be that PHP finally has a truly modern framework?

Are you no longer willing to sit on the sidelines? It’s time to dig in and discover why it is that in such a short timespan, Laravel has amassed such an enormous community of evangelists. Is it true, as they say, that Laravel actually makes PHP fun again? And could it be that PHP, as a framework, is no longer forever doomed to predominantly personal sites and ugly WordPress blogs? Nope; in fact, the PHP community just might find that, thanks to Laravel, Composer, and PHP 5.5, they’re about to experience the next renaissance of the web’s most popular server-side language.

To install the latest development version of Laravel (v4), you’ll need to first install Composer. Then, simply clone the repo, and install the dependencies. Git clone git://github.com/illuminate/app.git myApp and composer install. You’re ready to go!

Eloquent

Most PHP developers begin their journey by nesting countless lines of SQL directly into their frigid, unreadable PHP. Needless to say, excluding the most basic of websites, this quickly leads to an unmaintainable mess.
Remember when you first heard about Ruby on Rails’ ActiveRecord? Well, in the PHP end of the world, Eloquent is its premier implementation.
Need some examples?

001 // Fetch all tasks
002 $tasks = Task::all();
003 
004 // Fetch the task with an id of 1
005 $task = Task::find(1);
006 
007 // Update a task
008 $task = Task::find(1);
009 $task->title = ‘Put that cookie down!’;
010 $task->save();
011 
012 // Create a new task
013 Task::create([
014     ‘title’ => ‘Write article’
015 ]);
016 
017 // Delete a task
018 Task::find(1)->delete();

Folks, it’s not possible to write more readable code in PHP! Now it would be one thing if Eloquent only allowed you to perform basic CRUD operations on a table, but that’s certainly not the case.
Consider for a moment table relationships, such as a user and their respective tasks. In Laravel, after setting a quick lookup method for each model, we can easily handle one-to-one relationships – or any kind of association for that matter. Here are a few examples, just to whet your appetite.

001 // Get all tasks by the author with an id  of 1
002 $tasks = User::find(1)->tasks;
003 
004 // Get the author of a task
005 $author = Task::find(5)->user()->username;
006 
007 // Insert a new task by author
008 $task = new Task([ title: ‘Go to store.’    ]);
009 User::find(1)->tasks()->insert($task);

It’s not a stretch to consider Eloquent to be the best ActiveRecord implementation in the PHP language.

Composer packages

Beginning with Laravel 4 (currently in Alpha), the entire framework will be modularized and available as individual Composer packages.
Composer is a packaging system for PHP that is similar to PEAR, but better. It makes the process of dependency management as easy as possible.
Think of the existing framework ecosystem. Right now, you’re forced to live with each framework’s core set of features. You can’t choose to, say, use Eloquent in a CakePHP application. As you can imagine, this truth has lead to an insane process of reinventing the wheel over and over… and over.
Ladies and gentleman, the future of PHP is a modular one. Why install a bloated, massive framework, when you only require a few of its offerings? Well soon you won’t have to. Only require Eloquent in a simple project? Fine – not a problem at all! Simply install it through Composer, and move on!
So, if we’re moving to a more package-based, modular PHP world, how does Laravel fit in? Well, think of it as a predetermined collection of packages, wrapped in a bow! Even better, should you need to update to the latest version of the framework, it’s as easy as running composer update.
As an example of the flexibility that this provides, let’s add the popular Mockery testing library to a Laravel application. Begin with a new Laravel 4 project, and edit its composer.json file to require Mockery.

001 {
002 “require”: {
003 “illuminate/foundation”: “>=1.0.0”,
004 “mockery/mockery”: “dev-master”
005 },
006
007 “autoload”: {
008 “classmap”: [
009 “app/controllers”,
010 “app/models”,
011 “app/database/migrations”,
012 “app/tests/TestCase.php”
013 ]
014 }
015 }

Refer to packagist.org for a list of Composer packages, as well as installation instructions. Now that we’ve informed Composer that our application requires Mockery, we can install the applicable dependencies.

001 composer update 

And voila, that’s it! We can now use Mockery within our tests. This is the power of Composer and Laravel 4 at work! We have wheels; let’s stop creating new ones! Hundreds upon hundreds of packages are available through Packagist.org.

001 < ?php 
002 use Mockery as m; 
003 class ExampleTest extends PHPUnit_Framework_TestCase {} 

Routes

Most beginner PHP developers aren’t familiar with anything other than the most natural of route systems. Create a directory tree to match your desired URI, and move on. For example, add an index.php file to the following directory: blog/admin/, and now you can access it by browsing to: localhost:8888/blog/admin/index.php. Easy! Well, maybe at first, but you’ll likely find that you need more flexibility and control over which route is triggered in your application.
Laravel takes an incredibly simple and easy-to-use approach to routing. As an example, let’s write the necessary route to display a view for a user’s profile.

001 Route::get(‘users/{id}’, function($id) 
002 {
003 // find the user
004 $user = User::find($id); 005
006 // display view, and pass user object
007 return View::make(‘users.profile’)
008 ->with(‘user’, $user);
009 });

Now, when a user requests example.com/users/1, the users/profile.php view will be rendered.
Alternatively, we can use traditional controllers to instead handle the logic.

001 Route::get(‘users/{id}’, ‘Users@show’); 

Now, Controllers/Users.php will be responsible for rendering the view – specifically the show method.
001 < ?php 002 003 class UsersController extends Controller { 004 /** 005 * Display the specified resource. 006 */ 007 public function show($id) 008 { 009 // find the user 010 $user = User::find($id); 011 012 // display view, and pass user object 013 return View::make(‘users.profile’) 014 ->;with(‘user’, $user);
015 }
016 }

Easy Authentication

Nearly any web application of any substance will require a form of authentication on some level. Laravel provides a simple but easy to use interface for authenticating users.
Begin by creating a users table with the necessary fields for the username and password. Remember: this is a perfect use-case for a migration!
Laravel can then attempt to login a user – probably based upon user-supplied values from a form. Here’s a basic example, minus the validation aspect.

001 Route::post(‘login’, function() 
002 { $credentials = array(
003 ‘username’ => Input::get(‘username’),
004 ‘password’ => Input::get(‘password’)
005 ); 
006
007 // perform validation 
008
009 if ( Auth::attempt($credentials) ) 
010 { 
011 // Credentials match. Logged in! 
return Redirect::to(‘admin/profile’); 
012 } 
013 }); 

Note that behind the scenes Laravel will automatically hash the provided password and compare it against what’s stored in the user’s table.
Assuming that the user’s credentials match, the user ID will be stored in the session, and the user will be logged in. Upon subsequent requests, you can grab the currently logged in user’s username with:

001 $user = Auth::user()->username; 

Sending Email

Admit it: sending email through your application is always more complicated than it should be. Not anymore in Laravel 4!
Built on top of the popular SwiftMailer package, you’ll now find a new config/mail.php file in your application. This is where you can specify the necessary credentials to your email provider. Here’s a stripped down version of what you’ll find:

001 < ?php 002 // app/config/mail.php 003 004 return array( 005 ‘host’ => ‘smtp.example.com’,
006 ‘port’ => 2525,
007 ‘from’ => array(‘address’ => null, ‘name’ => null),
008 ‘encryption’ => ‘tls’,
009 ‘username’ => null,
010 ‘password’ => null,
011 );

Simply replace the values with those from your email server, accordingly.
Next, we need a view for the email. Let’s create one called ‘welcome.blade.php’, which will be used when a new member registers for our Justin Bieber fan website.

001 < ?php
002 // app/views/emails/welcome.blade.php
003
004 
005 
006 Hi there, {{ $user->name }}. Thanks again for signing up for the latest Justin Bieber news! We’ll look forward to seeing you around.
007
008 Thanks,
009 Management
010 
011 

With everything in place, let’s set up the necessary example route, and send the email.

001 Route::get(‘/’, function()
002 {
003 $user = User::find(1);
004 $data = [ ‘user’ => $user ];
005

006 // email view, data for view, closure to send email
007 Mail::send(‘emails/welcome’, $data, function($message) use($user)
008 {
009 $message
010 ->to($user->email)
011 ->subject(‘Welcome Bieber Fan!’)
012 ->attach(‘images/bieberPhoto. jpg’);
013 });
014 return ‘Welcome email sent!’;
015 });

Pretty simple, eh? We grab the new user from the table, and fire off an email to that user’s associated email address. Thanks to the SwiftMailer functionality, performing seemingly complex actions, such as attaching files, is a cinch! Now, every new member receives a photo of Justin Bieber upon signup. Perfect!

BFFs with Backbone

Laravel 4 makes the process of creating RESTful APIs as simple as humanly possible. The key is in how, by default, JSON will be returned from a route.
Let’s imagine that we need to return a list of all users as JSON. Well, we can accomplish that in a single line.

001 Route::get(‘users’, function()
002 { 
003 return User::all(); 
004 }); 

If you go ahead and run this route, a bit of JSON will be displayed, such as:

001 [{“id”:1,”username”:”jeffrey@example. com”},{“id”:2,”username”:”joe@example.com”}] 

Are you wondering where the password field is? In Laravel, within the table’s associated model, we can specify, via a $hidden property, which fields to hide from JSON output.
Now, with a JavaScript library like Backbone, we can fetch this data with ease.

001 var User = Backbone.Model.extend({});
002 var UsersCollection = Backbone.Collection. extend({
003 model: User,
004 url: ‘/users’
005 });
006
007 var users = new UsersCollection;
008 users.fetch();
009
010 users.toJSON(); // [Object, Object, Object]

What about fetching a single user instead? Well, we’d first need to set up the proper Laravel route:

001 Route::get(‘users/{id}’, function($id) { 002 return User::find($id); 
003 }); 

As we’ve learned, this will return the JSON for the requested user (minus the password). Next, we create a Backbone model, and fetch the data.

001 var User = Backbone.Model.extend({ 
002 urlRoot: ‘/users’ 
003 }); 
004
005 var user = new User({ id: 1 }); 
006 user.fetch(); // { id: 1, username: ‘jeffrey@example.com’ } 

Notice how the brunt of the work is on the
client-side? Our Laravel code is as barebones as it
can possibly be.

Migrations

If you’re exclusively a PHP developer, it’s likely that you haven’t yet experienced the joy of migrations, which were first popularised by the Ruby on Rails framework. Think of migrations as version control for your database. What would happen if, the day after you added that new field to your tasks table, you realised that it wasn’t needed after all? Well, you’d manually remove the field, right? But what about the other developers on your team? Their code may break if you don’t tell them. With migrations however, we merely roll back the previous migration, and continue on with our day! Even better, when pushing changes to your server, a simple php artisan migrate command will automatically update your production database. When combined with Laravel’s Schema Builder, this makes the process of managing databases as easy as possible.
Let’s create a migration to add a new users table to our database. From the command line:

001 php artisan migration:make create_users_ table –table=users –create 

In the snippet above, we specify the name of the table, as well as the –create flag. This is to specify that we’re creating a new table, rather than simply modifying an existing one.
This command will create a new migration file within our application. We can then leverage Laravel’s Schema class to prepare our table’s schema.

001 < ?php 002 003 use Illuminate\Database\Migrations\ Migration; 004 005 class CreateTasksTable extends Migration { 006 /** 007 * Run the migrations. 008 */ 009 public function up() 010 { 011 Schema::create(‘tasks’, function($table) 012 { 013 $table->increments(‘id’);
014 $table->string(‘title’);
015 });
016 }
017

018 /**
019 * Reverse the migrations.
020 */
021 public function down()
022 {
023 Schema::drop(‘tasks’);
024 }
025 }

Notice how this class offers two methods: up and down, which specify what action Laravel should take when executing a migration, as well as rolling it back.
In this case, on up(), we create a new table, tasks, and specify two fields for the id and title of the task, respectively. When rolling back the migration, we simply drop the table.
Run the migration by returning to the Terminal,
and typing:

001 php artisan migrate 

That’s it! You now have a brand new tasks table with two fields! Uh oh, need to roll it back? Simple:

001 php artisan migrate:rollback 

Goodbye tasks table.

Blade

Laravel’s Blade templating engine provides a clean syntax for views. For example, with regular PHP, to filter through a list of people and echo their respective names within a list item, we might write:

001 < ul> 
002 < ?php foreach($people as $p) : ?> 
003 < li>< ?php echo $p; ?> 
004 < ?php endforeach; ?> 
005 < /ul> 

This syntax can be applied to most of PHP’s control structures. It’s not too bad, but we can do better. Any Laravel view that contains the .blade.php file extension will be parsed accordingly. As a result, the previous snippet can be then replaced with:

001 < ul> 
002 @foreach($people as $p) 
003 < li>{{ $p }}< /li> 
004 @endforeach 
005 < /ul> 


Notice how variables to be echoed are wrapped within {{ }}, similar to what you’d find in a JavaScript templating engine, like Handlebars.
Blade may also be used for elegant layouts and master pages. Let’s create a base master view to demonstrate this functionality.

001 // views/layout.blade.php
002 < !doctype html>
003 < html>
004 < head>
005 < title>
006 < /head>
007 < body>
008 < div class=”container”>
009 @yield(‘container’)
010 < /div>
011 < /body>
012 < /html>
The @yield line is key here. This specifies that any child views with a section id of container should be nested there. Let’s next create a new view.

001 // views/home/hello.blade.php
002 @layout(‘layout’)
003 
004 @section(‘container’)
005 < h1>Hello, {{ $user->name }}!< /h1>
006 @endsection

Done! Easy master pages in PHP!

Resourceful Controllers

Without a bit of help, creating a RESTful service in PHP can prove to be somewhat difficult. Well, in Laravel 4, it couldn’t be simpler. The framework offers what we refer to as Restful Resources. Let’s test it out.
Within your routes file, specify a new resource.

001 Route::resource(‘tasks’, ‘TasksController’); 

This line of code designates that we want to create a new resource, tasks, and place the TasksController controller in charge of handling the logic for each route.
When following the principles of REST, this resource will automatically register routes for:
GET tasks (Show all tasks)
GET tasks/{id} (Show single task)
GET tasks/create (Display form to create a new task)
POST tasks (Create a new task)
GET task/{id}/edit (Edit single task)
PUT tasks/{id} (Update task)
DELETE tasks/{id} (Delete task)
Next, let’s create that TasksController, but, rather than doing it manually, we’ll let Artisan handle the boilerplate.

001 php artisan controller:make TasksController

This will create a new controllers/TasksController.php controller, and fill it with a bit of boilerplate.

001 < ?php
002
003 class TasksController extends Controller {
004 /**
005 * Display a listing of the resource.
006 */
007 public function index() {}
008
009 /**
010 * Show the form for creating a new resource.
011 */
012 public function create() {}
013
014 /**
015 * Store a newly created resource in storage.
016 */
017 public function store() {}
018
019 /**
020 * Display the specified resource.
021 */
022 public function show($id) {}
023
024 /**
025 * Show the form for editing the specified resource.
026 */
027 public function edit($id) {}
028
029 /**
030 * Update the specified resource in storage.
031 */
032 public function update($id) {}
033
034 /**
035 * Remove the specified resource from storage.
036 */
037 public function destroy($id) {}
038 }


Each of these methods will be triggered when the applicable RESTful route is triggered. So to display a form to create a new task, we’d load the applicable view within the create method, which will be triggered when example.com/tasks/create is requested. That form should POST to /tasks, in which case the store method will be triggered.
It couldn’t be cleaner!

Database Seeding

How many times have you found yourself manually seeding a database table with dummy records, for the purposes of testing? For me, well, it’s a large number! Laravel 4 allows us to specify a seed file for a table.
To try it out, create a new file with the same name as its respective table within the app/database/seeds directory of your application. This file should store an array of arrays, each containing the necessary key-value pairs. Here’s an example:
001 < ?php
002 // app/database/seeds/tasks.php
003 
004 return [
005 [ ‘title’ => ‘Go to the store’ ]
006 [ ‘title’ => ‘Finish Laravel article’ ]
007 [ ‘title’ => ‘Pick up eggs.’ ]
008 ]);

We’ve now described three new rows for the tasks table in our database. Let’s seed it.

001 php artisan db:seed 

Done!

Model Setters and Getters

There’s likely a variety of actions that you frequently trigger when setting or getting a field from a database table. For instance, when a user registers, to follow security best practices, we should always hash their password. Rather than manually doing the work, let’s instead update the User model, and specify that when setting a password, it should first be hashed.

001 < ?php 002 // models/User.php 003  004 class User extends Eloquent { 005 public function setPassword() 006 { 007 return Hash::make( $this->;password );
008 }
009 }

Easy! Now, we never have to worry about that piece of the puzzle when registering a new user. Naturally, the reverse option is available as well, should you need process a field’s value before getting it. What if we need to prettify a timestamp or name? This too can be accomplished through the model if you wish.

001 < ?php 002 // models/User.php 003 class User extends Eloquent { 004 public function fullName() 005 { 006 return $this->firstName . ‘ ‘ . $this->lastName;
007 }
008 }

This new fullName() method will now be available to our user instance.

001 echo User::find(1)->fullName(); // John Doe

Community (Conference)

Perhaps more important than anything else, Laravel, in a relatively short timespan, has amassed a thriving, evangelical community, comprised of some of the most influential developers in the PHP community.
Why is this important? Simple: with evangelism comes education and contribution. The biggest hurdle for a new framework is getting the word out, and showing folks how to use it. Luckily, Laravel excels in documentation and tutorials and screencasts – including a full course by yours truly!
Truth is, we’ve barely scratched the surface of what’s possible in Laravel. We’ve yet to cover Laravel’s error handling, PHPUnit integration, eager loading (before and after retrieving collections), and much more. Be sure to refer to the documentation to dig deeper into the framework, and keep your eyes peeled for the official release of Version 4!

Tags: ,
  • Tell a Friend
  • Follow our Twitter to find out about all the latest web development, news, reviews, previews, interviews, features and a whole more.
    • http://www.mercubuana.ac.id/ ululf01

      Hey thanks a lot for the article.

    • http://www.mercubuana.ac.id/ ululf01

      wow nice post
      thank you

    • http://www.atwright.co.uk/ Andy Wright

      Excellent article (almost a tutorial). However, lots of the code is visually broken — it needs to be within a PRE tag. :)

    • http://pinterest.com/fakeoakleysoaho/fake-oakleys/ fake oakley sunglasses

      near-mint condition, how good it is de- pends on who thecheap oakley sunglasses person is, wouldn one become increas- ingly apt to forget to make an entry? I copied his every action. First things first. and if you put the two together,discount oakley sunglasses, then gathered the rest of our luncheon detritus and put it in the trash. fake oakley sunglasses http://pinterest.com/fakeoakleysoaho/fake-oakleys/

    • http://shiooer.loxblog.com/ JarlsmalGuats

      Once i jogging avenue together with my friend I became attract with that high-end name. Just like the rr, Cartier and then many other luxury manufacturer in the world. In addition to my good friend informs me that it’s not simply our desire and also much more individuals across the world. Added consumers possess a aspiration A day they’ll person this particular high-class A single. Not just quite manufacturer them selves along with the ranking which patterns.

      Nevertheless, you it’s a night desire in my opinion and even more widespread consumers. As a result, the first time it’s very stressful can individual this specific high-end until eventually my spouse and i contain the Replica Cartier Wrist watches. Your day My spouse and i investigate world wide web, I have found a world wide web obtaining, and i also find this specific notice is so design and chic. And also the unbelievable would it be provides amount of string, you may find the tone you want in addition to just about any Reproduction Cartier Wrist watches their very own exclusive style and design. The design design plus the refreshing design makes you remarkable inside. By far the most crucial is this fact just inside the inexpensive paying attention to. Thus, maybe it’s undoubtedly will be able to select the concept. Ahead of My wife and i obtain this kind of Look-alike Cartier Designer watches, Irrrve never ever acquire one point online; simply because We estimate that on the web buying will not be protected. Look-alike Cartier Watches, I stage I became drastically wrong. Your on the internet purchasing is absolutely comfort and ease for our lure and we are able to decide on the actual satisfying just one.

      Duplicate Cartier Wrist watches help make my dream becoming reality by simply it is type fashion along with top end. This type of Look-alike Cartier Designer watches is actually well-designed together with complicate, you can observe the facts fashion inside it and you’ll delight in the excellent high quality. Right after the discover will not be just use pertaining to seeing some time, the actual Look-alike Cartier Timepieces with all the folks of favor styling, that will supply you with the fresh design you will need on this fashion entire world. Along with the operate within the brand of Identical Cartier Watches, many people can easily see your overall performance onto it. Your Duplicate Cartier Designer watches goes related to a great deal of a very long time; you are able to understand the report beyond the sitting on the idea. In several watch generating organization, the actual Replicate Cartier Wrist watches has become your primary onto it. and its particular greater popularity is really test their very best to satisfy men and women necessity, in addition to accomplish their particular magnificent wonderland.

      I suppose I came to be lucky to own this opportunity to non-public this particular luxurious Duplicate Cartier Watches through this low-cost. Nevertheless it can be trustworthy for those; a lot of people might exclusive your style in addition to excellent Duplicate Cartier Timepieces, exactly like many of us individual this specific high-class.

      cheap mens watches|

    • http://ofertasdiaria.com.ar/?p=12897 Leila

      . Rycerz skrzywił się. Jak najbardziej niechrześcijański owo Leila władca, tolerować trochę
      takiego
      pod spodem samym zamkiem. Księżyc zachodził wcześniej.
      Straże nawoływały się bez mała rzadziej.

      Czas była załapać w największym stopniu.

    • http://narrowpathstohigherplaces.com/love-letters-on-letting-the-sun-go-down/ time management techniques

      My brother suggested I might like this blog. He was
      totally right. This post actually made my day.
      You cann’t imagine just how much time I had spent for this information! Thanks!

    • http://%URL% the text the romance back review

      Hello! I just wish to give you a big thumbs up for your great information you have here
      on this post. I am coming back to your site for more soon.

    • http://%URL% SMTP2GO Review

      What a information of un-ambiguity and preserveness of precious know-how concerning unpredicted feelings.

    • http://inamasei.com/wp-login.php?redirect_to=http%3A%2F%2Finamasei.com%2Fblog%2Fexchangers%2F hyip

      Woah this website is definitely impressive everyone loves examining your content regularly. Keep up the fantastic works of art! You realize, plenty of person’s are seeking all over for this data, you may aid them enormously.

    • social networking site

      I was on Facebook till just lately, when I made a decision I was fed up with all the inane trivia that continually dribbled down my
      timeline thingy, so I terminated it. I’ve Twitter, but do not use it a lot, and I lately also killed Linkedin, as I did not like how it seemed to get hold of all my ‘friends’ by itself.

    • http://whattosaytogirls.net what to say to attract girls

      I’ve been browsing online more than three hours lately, but I by no means discovered any fascinating article like yours. It’s lovely worth sufficient for me.
      In my opinion, if all website owners and bloggers made excellent content material as you probably
      did, the internet can be much more useful than ever before.

    • http://crystleol.Revelife.com/773326075/useful-gardening-tips/ gardening Tips

      This is the right website for anybody who wishes to understand this topic.
      You realize so much its almost tough to argue with you
      (not that I really will need to…HaHa). You definitely put a fresh spin on a subject that’s been written about for decades. Great stuff, just excellent!

    • http://donterubinzen.wordpress.com/ what is tadalafil generic

      o What are the constituents of male enhancement pills.
      It is estimated that more than 16 million people in the UK suffer from type-2 diabetes – a
      health condition that can adversely affect a man’s erection. Viagra, however, can only be viewed as short term solution; it makes an individual forget about seeking other treatments.

    • http://www.77line.com/?p=737 my lead system pro

      Tremendous issues here. I am very glad to peer your article.
      Thanks a lot and I’m looking forward to touch you. Will you kindly drop me a e-mail?

    • http://agnesrice906.jimdo.com/2013/06/19/green-mountain-coffee-coupons-printable-huge-savings/ new coupon

      After exploring a few of the blog articles on your web page, I really appreciate your way of blogging.

      I added it to my bookmark website list and will be checking back in the near future.
      Take a look at my website as well and tell me your opinion.