Creating and Using Composer Packages

Exclusive offer: get 50% off this eBook here
Laravel Application Development Cookbook

Laravel Application Development Cookbook — Save 50%

Over 90 recipes to learn all the key aspects of Laravel, including installation, authentication, testing, and the deployment and integration of third parties in your application with this book and ebook

$26.99    $13.50
by Terry Matula | October 2013 | AJAX Cookbooks Java PHP Web Development

In this article by Terry Matula, author of the book, Laravel Application Development Cookbook, we will cover:

  • Downloading and installing packages
  • Using the Generators package to set up an app
  • Creating a Composer package in Laravel
  • Adding your Composer package to Packagist
  • Adding a non-Packagist package to Composer
  • Creating a custom artisan command

(For more resources related to this topic, see here.)

Using Bundles

One of the great features in Laravel is the ease in which we can include the class libraries that others have made using bundles. On the Laravel site, there are already many useful bundles, some of which automate certain tasks while others easily integrate with third-party APIs.

A recent addition to the PHP world is Composer, which allows us to use libraries (or packages) that aren't specific to Laravel.

In this article, we'll get up-and-running with using bundles, and we'll even create our own bundle that others can download. We'll also see how to incorporate Composer into our Laravel installation to open up a wide range of PHP libraries that we can use in our application.

Downloading and installing packages

One of the best features of Laravel is how modular it is. Most of the framework is built using libraries, or packages, that are well tested and widely used in other projects. By using Composer for dependency management, we can easily include other packages and seamlessly integrate them into our Laravel app.

For this recipe, we'll be installing two popular packages into our app: Jeffrey Way's Laravel 4 Generators and the Imagine image processing packages.

Getting ready

For this recipe, we need a standard installation of Laravel using Composer.

How to do it...

For this recipe, we will follow these steps:

  1. Go to https://packagist.org/.
  2. In the search box, search for way generator as shown in the following screenshot:

  3. Click on the link for way/generators :

  4. View the details at https://packagist.org/packages/way/generators and take notice of the require line to get the package's version. For our purposes, we'll use "way/generators": "1.0.*" .
  5. In our application's root directory, open up the composer.json file and add in the package to the require section so it looks like this:

    "require": { "laravel/framework": "4.0.*", "way/generators": "1.0.*" },

  6. Go back to http://packagist.org and perform a search for imagine as shown in the following screenshot:

  7. Click on the link to imagine/imagine and copy the require code for dev-master :

  8. Go back to our composer.json file and update the require section to include the imagine package . It should now look similar to the following code:

    "require": { "laravel/framework": "4.0.*", "way/generators": "1.0.*", "imagine/imagine": "dev-master" },

  9. Open the command line, and in the root of our application, run the Composer update as follows:

    php composer.phar update

  10. Finally, we'll add the Generator Service Provider, so open the app/config/app.php file and in the providers array, add the following line:

    'Way\Generators\GeneratorsServiceProvider'

How it works...

To get our package, we first go to packagist.org and search for the package we want. We could also click on the Browse packages link. It will display a list of the most recent packages as well as the most popular. After clicking on the package we want, we'll be taken to the detail page, which lists various links including the package's repository and home page. We could also click on the package's maintainer link to see other packages they have released.

Underneath, we'll see the various versions of the package. If we open that version's detail page, we'll find the code we need to use for our composer.json file. We could either choose to use a strict version number, add a wildcard to the version, or use dev-master, which will install whatever is updated on the package's master branch. For the Generators package, we'll only use Version 1.0, but allow any minor fixes to that version. For the imagine package, we'll use dev-master, so whatever is in their repository's master branch will be downloaded, regardless of version number.

We then run update on Composer and it will automatically download and install all of the packages we chose. Finally, to use Generators in our app, we need to register the service provider in our app's config file.

Using the Generators package to set up an app

Generators is a popular Laravel package that automates quite a bit of file creation. In addition to controllers and models, it can also generate views, migrations, seeds, and more, all through a command-line interface.

Getting ready

For this recipe, we'll be using the Laravel 4 Generators package maintained by Jeffrey Way that was installed in the Downloading and installing packages recipe. We'll also need a properly configured MySQL database.

How to do it…

Follow these steps for this recipe:

  1. Open the command line in the root of our app and, using the generator, create a scaffold for our cities as follows:

    php artisan generate:scaffold cities --fields="city:string"

  2. In the command line, create a scaffold for our superheroes as follows:

    php artisan generate:scaffold superheroes --fields="name:string,
    city_id:integer:unsigned"

  3. In our project, look in the app/database/seeds directory and find a file named CitiesTableSeeder.php. Open it and add some data to the $cities array as follows:

    <?php class CitiesTableSeeder extends Seeder { public function run() { DB::table('cities')->delete(); $cities = array( array( 'id' => 1, 'city' => 'New York', 'created_at' => date('Y-m-d g:i:s',time()) ), array( 'id' => 2, 'city' => 'Metropolis', 'created_at' => date('Y-m-d g:i:s',time()) ), array( 'id' => 3, 'city' => 'Gotham', 'created_at' => date('Y-m-d g:i:s',time()) ) ); DB::table('cities')->insert($cities); } }

  4. In the app/database/seeds directory, open SuperheroesTableSeeder.php and add some data to it:

    <?php class SuperheroesTableSeeder extends Seeder { public function run() { DB::table('superheroes')->delete(); $superheroes = array( array( 'name' => 'Spiderman', 'city_id' => 1, 'created_at' => date('Y-m-d g:i:s', time()) ), array( 'name' => 'Superman', 'city_id' => 2, 'created_at' => date('Y-m-d g:i:s', time()) ), array( 'name' => 'Batman', 'city_id' => 3, 'created_at' => date('Y-m-d g:i:s', time()) ), array( 'name' => 'The Thing', 'city_id' => 1, 'created_at' => date('Y-m-d g:i:s', time()) ) ); DB::table('superheroes')->insert($superheroes); } }

  5. In the command line, run the migration then seed the database as follows:

    php artisan migrate php artisan db:seed

  6. Open up a web browser and go to http://{your-server}/cities. We will see our data as shown in the following screenshot:

  7. Now, navigate to http://{your-server}/superheroes and we will see our data as shown in the following screenshot:

How it works...

We begin by running the scaffold generator for our cities and superheroes tables. Using the --fields tag, we can determine which columns we want in our table and also set options such as data type. For our cities table, we'll only need the name of the city. For our superheroes table, we'll want the name of the hero as well as the ID of the city where they live.

When we run the generator, many files will automatically be created for us. For example, with cities, we'll get City.php in our models, CitiesController.php in controllers, and a cities directory in our views with the index, show, create, and edit views. We then get a migration named Create_cities_table.php, a CitiesTableSeeder.php seed file, and CitiesTest.php in our tests directory. We'll also have our DatabaseSeeder.php file and our routes.php file updated to include everything we need.

To add some data to our tables, we opened the CitiesTableSeeder.php file and updated our $cities array with arrays that represent each row we want to add. We did the same thing for our SuperheroesTableSeeder.php file. Finally, we run the migrations and seeder and our database will be created and all the data will be inserted.

The Generators package has already created the views and controllers we need to manipulate the data, so we can easily go to our browser and see all of our data. We can also create new rows, update existing rows, and delete rows.

Laravel Application Development Cookbook Over 90 recipes to learn all the key aspects of Laravel, including installation, authentication, testing, and the deployment and integration of third parties in your application with this book and ebook
Published: October 2013
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Creating a Composer package in Laravel

Using Laravel's Workbench, we can easily create a package that can be used and installed by Composer. We can also add functionality so that the package integrates seamlessly into our Laravel app. In this recipe, we'll be creating a simple package that will display a list of Vimeo videos for a specified user.

Getting ready

For this recipe, we'll need a standard Laravel installation.

How to do it…

To complete this recipe, follow these steps:

  1. In the app/config directory, open the workbench.php file and update it with the following information:

    <?php return array( 'name' => 'Terry Matula', 'email' => 'terrymatula@gmail.com', );

  2. In the command line, use artisan to set up our package:

    php artisan workbench matula/vimeolist --resources

  3. Find the directory that will hold our source files and create a file named Vimeolist.php. In this example, we would put the file in workbench/matula/vimeolist/src/Matula/Vimeolist/:

    <?php namespace Matula\Vimeolist; class Vimeolist { private $base_url = 'http://vimeo.com/api/v2/{username}/videos.json'; private $username; public function __construct($username = 'userscape') { $this->setUser($username); return $this; } /** * Set the username for our list * * @return void */ public function setUser($username = NULL) { $this->username = is_null($username) ? $this->username : urlencode($username); return $this; } /** * Set up the url and get the contents * * @return json */ private function getFeed() { $url = str_replace('{username}', $this->username,$this->base_url); $feed = file_get_contents($url); return $feed; } /** * Turn the feed into an object * * @return object */ public function parseFeed() { $json = $this->getFeed(); $object = json_decode($json); return $object; } /** * Get the list and format the return * * @return array */ public function getList() { $list = array(); $posts = $this->parseFeed(); foreach ($posts as $post) { $list[$post->id]['title'] = $post->title; $list[$post->id]['url'] = $post->url; $list[$post->id]['description'] = $post->description; $list[$post->id]['thumbnail'] = $post->thumbnail_small; } return $list; } }

  4. In the same directory as the file we just created, open the file named VimeolistServiceProvider.php and update it:

    <?php namespace Matula\Vimeolist; use Illuminate\Support\ServiceProvider; class VimeolistServiceProvider extends ServiceProvider { /** * Indicates if loading of the provider is deferred. * * @var bool */ protected $defer = false; /** * Bootstrap the application events. * * @return void */ public function boot() { $this->package('matula/vimeolist'); } /** * Register the service provider. * * @return void */ public function register() { $this->app['vimeolist'] = $this->app->share(function($app) { return new Vimeolist; }); } /** * Get the services provided by the provider. * * @return array */ public function provides() { return array('vimeolist'); } }

  5. Open the app.php file in the app/config directory, and in the providers array, add our service provider as follows:

    'Matula\Vimeolist\VimeolistServiceProvider',

  6. In the command line, run the following command:

    php composer.phar dump-autoload

  7. In routes.php, add a route to display the data as follows:

    Route::get('vimeo/{username?}', function($username = null) use ($app) { $vimeo = $app['vimeolist']; if ($username) { $vimeo->setUser($username); } dd($vimeo->getList()); });

How it works...

Our first step is to update our workbench's configuration file to hold our name and e-mail address. This will then be used for any other packages that we create in Laravel.

Next, we run the artisan command to create the files we need for our package. By using the --resources flag, it will also generate other files and directories that can be used specifically for Laravel. Once it's completed, there will be a new folder in our workbench directory that holds all our package's files. After drilling down into the directories, we'll get to a directory that holds our service provider file, and in this directory, we'll add our class file.

This example class will simply get a list of videos for a user from the Vimeo API. We have methods that will allow us to set a username, get the contents of the API endpoint, turn the JSON into a PHP object, and then create and return a formatted array. As a best practice, we should also make sure our code is tested and that we can put those files in the test directory.

To better integrate with Laravel, we need to update the service provider. We first update the register method and set the name we want to pass to Laravel's app variable and then we update the provides method to return the package name. Next, we need to update our app configuration file to actually register the service provider. Then, once we run the dump-autoload command in Composer, our new package will be available to use.

Finally, we create a route to interact with the package. We'll have one optional parameter, that is, the username. We also need to make sure the $app variable is available in our route. Then, when we call $app['vimeolist'], the service provider will automatically instantiate our class and allow us to access the Vimeo list. For our purposes, we're only using the dd() helper function of Laravel to display the data, but we could also pass it to a view and make it look nicer.

There's more...

Laravel also has the option to create a facade for our package, so we could call it using something similar to $vimeo = Vimeolist::setUser(). There are also many other options for packages that can be found in the documentation at http://laravel.com/docs/packages.

Adding your Composer package to Packagist

To make it easier to distribute our packages, we should submit them to the website packagist.org. In this recipe, we'll see how to set up our package on GitHub and add it to Packagist.

Getting ready

For this recipe, we'll need to have completed the Creating a Composer package in Laravel recipe, and we'll also need an active GitHub account.

How to do it...

To complete this recipe, follow these steps:

  1. In the command line, move to the workbench/matula/vimeolist directory and set up our git repository as follows:

    git init git add -A git commit –m 'First Package commit'

  2. Create a new GitHub repository at https://github.com/new and give it the name vimeolist.
  3. Add our package to GitHub:

    git remote add origin git@github.com:{username}/vimeolist.git git push –u origin master

  4. Go to https://packagist.org/login/ and log in using your GitHub account.
  5. Click on the green Submit Package button shown in the following screenshot:

  6. In the Repository URL text field, add the Git read-only URL from GitHub as shown in the following screenshot:

  7. Click on Check, and if everything works, click on Submit.

How it works...

We begin by creating a git repository in our package's main directory. We then create a repository in GitHub for our files, add that remote to our local repository, and then push our local repository to GitHub.

On the Packagist site, we log in using our GitHub account and allow the packagist.org access. Then, we submit our packages at https://packagist.org/packages/submit using the GitHub URL from our repository. After clicking on Check , Packagist will look through the code and format it for use with Composer. If there are any errors, we will be prompted with what we need to do to fix them.

If everything checks out and we click on Submit , our package will then be listed on the Packagist website.

See also

  • The Creating a Composer package in Laravel recipe
Laravel Application Development Cookbook Over 90 recipes to learn all the key aspects of Laravel, including installation, authentication, testing, and the deployment and integration of third parties in your application with this book and ebook
Published: October 2013
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Adding a non-Packagist package to Composer

Adding a single line to our composer.json file and having Composer automatically download and install a package is great, but it requires the package to be available on packagist.org. In this recipe, we'll see how to install packages that aren't available on Packagist.

Getting ready

For this recipe, we'll need a standard Laravel installation.

How to do it...

To complete this recipe, follow these steps:

  1. On GitHub, we'll need to find a package we want to use. For this example, we'll use the UniversalForms package found at https://github.com/wesleytodd/Universal-Forms-PHP.
  2. Open our main composer.json file and update the require section as follows:

    "require": { "laravel/framework": "4.0.*", "wesleytodd/universal-forms": "dev-master" },

  3. In composer.json, under the require section, add the repository we want to use:

    "repositories": [ { "type": "vcs", "url": "https://github.com/wesleytodd/Universal-Forms-PHP" } ],

  4. In the command line, update Composer as follows:

    php composer.phar update

  5. Open the app/config/app.php file and update the providers array with the following line:

    'Wesleytodd\UniversalForms\Drivers\Laravel\UniversalFormsServiceProvider',

  6. In routes.php, instantiate the class and use it on our routes as follows:

    $form_json = '{ "action" : "uform", "method" : "POST", "fields" : [ { "name" : "name", "type" : "text", "label" : "Name", "rules" : ["required"] }, { "name" : "email", "type" : "email", "label" : "Email", "value" : "myemail@example.com", "rules" : ["required", "email"] }, { "name" : "message", "type" : "textarea", "label" : "Message", "rules" : ["required", "length[30,0]"] } ] }'; $uform = new Wesleytodd\UniversalForms\Drivers\Laravel\Form($form_json); Route::get('uform', function() use ($uform) { return $uform->render(); }); Route::post('uform', function() use ($uform) { // validate $valid = $uform->valid(Input::all()); if ($valid) { // Could also save to database dd(Input::all()); } else { // Could redirect back to form dd($uform->getErrors()); } });

How it works...

Our first step is to add in the line for the required packages just like with other Composer packages. However, since this package isn't available on packagist.org, it will throw an error if we try to update Composer. To get it to work, we need to add in a repository for Composer to use. Composer has many different options for using other repositories, and they can be found at http://getcomposer.org/doc/05-repositories.md#vcs.

Next, we update Composer and it will install the package for us. Since this package comes with a Laravel service provider, we then update our configuration file to register it.

Now we're able to use the package in our app. For our purposes, we'll instantiate the class outside of the routes and pass it into the routes' closure. Then we can use the library like normal. This particular package will take a JSON string or file and automatically create our form output for us.

Creating a custom artisan command

Laravel's artisan command-line tool makes many tasks easy to accomplish. If we want to make our own tasks and use artisan to run them, the process is quite simple. In this recipe, we'll see how to make an artisan task that automatically creates an HTML5 skeleton in our views directory.

Getting ready

For this recipe, we'll need a standard Laravel installation.

How to do it...

To complete this recipe, follow these steps:

  1. In the command line, run the artisan command to create our needed files:

    php artisan command:make SkeletonCommand

  2. In the app/commands directory, open the SkeletonCommand.php file and update the code as follows:

    <?php use Illuminate\Console\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Illuminate\Filesystem\Filesystem as File; class SkeletonCommand extends Command { /** * The console command name. * * @var string */ protected $name = 'skeleton:make'; /** * The console command description. * * @var string */ protected $description = 'Creates an HTML5 skeleton view.'; /** * File system instance * * @var File */ protected $file; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); $this->file = new File(); } /** * Execute the console command. * * @return void */ public function fire() { $view = $this->argument('view'); $file_name = 'app/views/' . $view; $ext = ($this->option('blade')) ? '.blade.php' :'.php'; $template = '<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title></title> <link rel="stylesheet" type="text/css"media="screen"
    href="css/style.css"/> <script type="text/javascript" src = "http://ajax.googleapis.com/
    ajax/libs/jquery/2.0.3/jquery.min.js"> </script> <!--[if IE]> <script src = "http://html5shiv.googlecode.com/svn/trunk/
    html5.js"></script> <![endif]--> </head> <body> </body> </html>'; if (!$this->file->exists($file_name)) { $this->info('HTML5 skeleton created!'); return $this->file->put($file_name . $ext,$template) !== false; } else { $this->info('HTML5 skeleton created!'); return $this->file->put($file_name . '-' .time() . $ext, $template)
    !== false; } $this->error('There was a problem creating yourHTML5 skeleton'); return false; } /** * Get the console command arguments. * * @return array */ protected function getArguments() { return array( array('view', InputArgument::REQUIRED, 'The name of the view.'), ); } /** * Get the console command options. * * @return array */ protected function getOptions() { return array( array('blade', null, InputOption::VALUE_OPTIONAL, 'Use Blade templating?',
    false), ); } }

  3. In the app/start directory, open the artisan.php file and add the following line:

    Artisan::add(new SkeletonCommand);

  4. In the command line, test out the new command:

    php artisan skeleton:make MyNewView --blade=true

How it works...

Our first step is to use the command:make function of artisan and pass in the name of the command we want to use. After this runs, we'll find a new file in our app/commands directory with the same name as the name we chose.

In our SkeletonCommand file, we start by adding in a name. This will be the command to which artisan will respond. Next, we set a description, which will display when we list out all the artisan commands.

For this command, we'll be accessing the filesystem, so we need to make sure to add Laravel's Filesystem class and that we instantiate it in our constructor. Then, we come to the fire() method. This is where all the code we want to run should go. For our purpose, we use a single argument to determine what our view file name will be, and if the --blade parameter is set to true, we'll make it a blade file. Then, we create a string that holds our HTML5 skeleton, though we could also make this a separate file and pull in the text.

We then create the new file using the template as our HTML and display a success message in the console.

Summary

In this article we covered the following topics:

  • Downloading and installing packages
  • Using the Generators package to set up an app
  • Creating a Composer package in Laravel
  • Adding your Composer package to Packagist
  • Adding a non-Packagist package to Composer
  • Creating a custom artisan command

Resources for Article:


Further resources on this subject:


About the Author :


Terry Matula

Terry Matula is a web developer and Laravel advocate based in Austin, TX.

He's been a passionate computer enthusiast since he first played Oregon Trail on an Apple//e. He started programming in BASIC at a young age, making simple Scott Adams-like games on a Commodore Vic-20. Since then, he's worked as a developer using Flash/ActionScript, ASP.NET, PHP, and numerous PHP frameworks, with Laravel being his favorite by far.

He blogs web development tips and tricks at his website http://terrymatula.com

Books From Packt


Instant Zend Framework 2.0
Instant Zend Framework 2.0

JavaScript and JSON Essentials
JavaScript and JSON Essentials

RESTful PHP Web Services
RESTful PHP Web Services

Laravel Starter
Laravel Starter

CodeIgniter for Rapid PHP Application Development
CodeIgniter for Rapid PHP Application Development

Jasmine JavaScript Testing
Jasmine JavaScript Testing

Instant Lift Web Applications How-to
Instant Lift Web Applications How-to

RESS Essentials
RESS Essentials


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
L
b
E
W
b
B
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software