Wern Ancheta

Adventures in Web Development.

URL Manipulation With Purl

| Comments

In PHP projects, there’s often a need to construct URL’s to be used for making requests to API’s. Normally we would concatenate the different pieces of the URL together in order to make up a complete URL where the request is made. In this tutorial, I’ll be talking about Purl. This library reduces the need for concatenation. With this library, you can manipulate a specific URL anyway you want. You can do things like parsing the URL so you can get it’s individual parts such as the scheme, port, path, query parameters and even fragments. These parts can then be modified any way you want.

Installation

You can use Composer to install Purl.

1
composer require jwage/purl

Usage

To use Purl, you have to include the vendor autoload file and then use the Url class in the Purl namespace. Optionally, you can give it an alias so you only have to use it instead of the namespace + class syntax.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

use Purl\Url as purl;
?>

Getting a URL

To use Purl, create a new instance of it using the alias you’ve assigned earlier and then pass in the URL that you want to manipulate. In order to get the modified URL back, call the getUrl method.

1
2
3
4
<?php
$url = new purl('http://wern-ancheta.com');
echo $url->getUrl(); //http://wern-ancheta.com
?>

In the above code, the URL wasn’t really manipulated yet so it will return the same thing that you passed.

Getting Parts of the URL

You can use any of the following properties to extract different parts of the URL. Note that the subdomain in this specific URL will return an empty string since there’s no subdomain. If the URL was http://blog.wern-ancheta.com then the value for subdomain will be blog. Another thing to note is the canonical property. This returns everything in the URL except the scheme and the fragment. Also the publicSuffix is the first value, followed by the registerableDomain. So instead of wern-ancheta.com, you will see com.wern-ancheta. Lastly, the port is an empty string since it wasn’t explicitly specified in the URL. By default, website uses port 80 and it doesn’t need to be explicitly specified.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$url = new purl('http://wern-ancheta.com/some/path?query=some_query&another=query#fragment');

echo $url->scheme; // http
echo $url->port; // empty string
echo $url->publicSuffix; // com
echo $url->registerableDomain; // wern-ancheta.com
echo $url->subdomain; // empty string
echo $url->canonical; // com.wern-ancheta/some/path?query=some_query&another=query
echo $url->path; // /some/path
echo $url->query; // query=some_query&another=query
echo $url->fragment; // fragment
?>

Setting Parts of the URL

If you want to set the different parts of the URL, you have to use the static method parse and then pass in the URL you want to manipulate. This allows you to chain the set methods. If you initialize a new instance of the purl class instead, you will get an error.

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$url = purl::parse('http://wern-ancheta.com')
    ->set('scheme', 'https')
    ->set('port', '1122')
    ->set('user', 'wern')
    ->set('pass', 'ancheta')
    ->set('path', 'some/path')
    ->set('query', 'query1=value1&query2=value2')
    ->set('fragment', 'my-fragment');

echo $url->getUrl(); // https://wern:ancheta@wern-ancheta.com:1122/some/path?query1=value1&query2=value2#my-fragment
?>

If you want to individually add paths to the URL, you have to initialize a new instance of the purl class.

1
2
3
4
5
<?php
$url = new purl('http://wern-ancheta.com');
$url->path->add('my')->add('awesome')->add('page');
echo $url->getUrl(); //http://wern-ancheta.com/my/awesome/page
?>

If you need to individually set the query parameters, you can use teh setData method. This allows you to pass in an associative array with its key being the query and the value being the value for that query.

1
2
3
4
5
6
7
8
<?php
$url = new purl('http://wern-ancheta.com');
$url->query->setData(array(
    'query1' => 'value1',
    'query2' => 'value2'
));
echo $url->getUrl(); //http://wern-ancheta.com/?query1=value1&query2=value2
?>

If it’s the other way around, and you want to extract the query parameters from a specific URL. Here’s the way you do it.

1
2
3
4
<?php
$url = new purl('http://wern-ancheta.com?query1=value1&query2=value2');
print_r($url->query->getData()); // Array ( [query1] => value1 [query2] => value2 )
?>

Extracting URL’s

One bonus feature of this library is that it allows you to extract URL’s in a specific string of text. Call the static extract method to use this. You can then extract each individual URL by using the key.

1
2
3
4
5
6
<?php
$str = "Hey I'm a string with url's in it http://google.com and another one http://github.com";
$urls = purl::extract($str);
echo $urls[0] . "<br>";
echo $urls[1];
?>

Note that each extracted URL’s are Purl URL instances of their own. So you can actually extract or manipulate individual parts as well.

1
2
3
4
5
6
<?php
echo $urls[0]->registerableDomain; //google.com

$urls[0]->path->add('my')->add('awesome')->add('path');
echo $urls[0]->getUrl(); //http://google.com/my/awesome/path
?>

Conclusion

In this tutorial, you’ve learned about Purl, a URL manipulation library for PHP. For more information, check out their official Github project page.

Getting Started With Swiftmailer

| Comments

In this tutorial I’m going to walk you through how to use Swift Mailer in your PHP applications. Swift Mailer, as the name suggests is a library for sending emails in PHP.

Installation

You can install Swiftmailer through Composer by executing the following command.

1
composer require swiftmailer/swiftmailer

Usage

To start sending emails you first have to create a new instance of the Swift_SmtpTransport class. This accepts the host as its first argument and the port as its second. You can then set your username and password by calling the setUsername and setPassword methods. So for example, you want to use your mandrill for sending emails, you can use the following. Just replace the username and password to that of your mandrill account.

1
2
3
$transport = Swift_SmtpTransport::newInstance('smtp.mandrillapp.com', 587)
  ->setUsername('your-mandrill-username')
  ->setPassword('your-mandrill-password');

Next, create a new Swift mailer instance and passing in the transport object as the argument. You can use this later on to send messages.

1
$mailer = Swift_Mailer::newInstance($transport);

You can create a new message by creating a new instance of Swift_Message class. From there, call the setSubject, setBody, setFrom and setTo methods to add the details of the email.

1
2
3
4
5
$message = Swift_Message::newInstance()
  ->setSubject('YOUR-SUBJECT')
  ->setBody('BODY-OF-YOUR-MESSAGE')
  ->setFrom(array('YOUR-EMAIL@HOST.COM' => 'YOUR-USER-NAME'))
  ->setTo(array('EMAIL-TO@HOST.COM' => 'NAME-TO@HOST.COM'));

Optionally, you can set an alternative body:

1
$message->addPart('YOUR-ALTERNATIVE-BODY', 'text/html');

You can also attach a file:

1
$message->attach(Swift_Attachment::fromPath('/path/to/file.pdf'));

If you want to send to multiple clients, then you can pass in additional items to the setTo method:

1
$message->setTo(array('EMAIL-TO@HOST.COM' => 'NAME-TO@HOST.COM', 'ANOTHER-EMAIL@HOST.COM' => 'ANOTHER-NAME@HOST.COM'));

Finally, you can send the message by calling the send method in the mailer instance that you have created earlier. Pass in the message as its argument.

1
2
3
4
5
6
try {
    $response = $mailer->send($message);
}catch (Exception $e){
    echo 'error occured while trying to send your message';
    echo $e->getMessage();
}

The send method will return 1 as its response if the message was sent successfully. If not then it will return an error, that’s why you need to wrap it in a try catch block.

If you’re using Laravel, SwiftMailer is already added as a dependency by default. All you have to do is update the mail configuration file. If you’re using another framework, you can just follow the examples here.

Conclusion

That’s it! In this tutorial you’ve learned how to use SwiftMailer on your php applications. If you want to learn more, be sure to check out the official docs.

Using the Intervention Image Library in PHP

| Comments

In this tutorial I’ll be showing you how to manipulate images in PHP using the Intervention Image library. In the PHP applications that I write, I primarily use intervention image for resizing images into smaller one’s. But aside from that, there are other things that this library can do.

Installation and Setup

To use intervention image, you need to have ImageMagick installed. In Ubuntu, you can do that by executing the following command from your terminal:

1
sudo apt-get install imagemagick

On your working directory, execute the following to install Intervention Image.

1
composer require intervention/image

This command uses Composer. If you don’t have it already, check out the downloads page and install it on your system.

Create a new PHP file and name it tester.php. This will be the file that you’re going to use for the rest of this tutorial.

To use the library, require the autoload file in the vendor directory. This allows you to include the Intervention Image library into your current file. You can then give an alias to the ImageManagerStatic class and use it for manipulating images.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

use Intervention\Image\ImageManagerStatic as Image;
?>

Create Image Instance

The first thing that you need to do when working with this library is to create an instance of the image from source. This is like saving a copy of the image into memory so that it can be easily manipulated. Any changes made to the image are only in memory until you choose to commit it to the filesystem.

1
2
3
<?php
$img = Image::make('images/a.jpg');
?>

Resizing Images

You can resize images by calling the resize method in the image instance that you’ve created. In the example below, the image is resized to exactly 50x50 pixels. It doesn’t matter if the image is distorted in the process. So if you have an image which is 300x600 (where 300 is the width and 600 is the height), the height will have to get squashed. This results in a sandwich-like image.

1
2
3
<?php
$img->resize(50, 50);
?>

If you don’t want that to happen, you need to utilize aspect ratio. This allows you to supply only either the width or the height. In the example below, the width is optional and the height is 50. This resizes the image to have a height of 50 and the width can have any value as long as the aspect ratio is the same.

1
2
3
4
5
<?php
$img->resize(null, 50, function ($constraint) {
    $constraint->aspectRatio();
});
?>

Adjusting Brightness, Contrast and Opacity

To adjust the brightness of an image, you can use values between 100 and -100. 100 being the brightess and -100 being the darkest. So you’ll only really see a white image if you supply 100 as the value and a black image if the value is -100. Positive values are used to bring the brightness up and negative to bring it down. In the example below, the brightness is adjusted to 25% of the default brightness of the image.

1
2
3
<?php
$img->brightness(25);
?>

To adjust the contrast, yup you guessed it right!, use the the contrast method. Just like the brightness method this accepts values between 100 and -100.

1
2
3
<?php
$img->contrast(25);
?>

To adjust the opacity, supply a value between 0 and 100 to the opacity method. With 100 being the full opacity and 0 being the full transparency. Note that adjusting the opacity of an image takes a bit of time. On my testing, it took a bit longer for it to finish than the other operations I’ve used so far.

1
2
3
<?php
$img->opacity(25);
?>

Cropping

Cropping images can be done by calling the crop method. This accepts 2 required arguments and 2 optional. The first and second arguments are the width and height of the area to be cropped. And the optional third and fourth arguments are the X and Y axis of the starting points of the crop area. If you do not supply those values, Intervention Image is going to assume that you want to crop at the very center of the image moving outward. That’s what the example below does.

1
2
3
<?php
$img->crop(100, 100);
?>

If you’re planning to implement a cropping functionality in your PHP application, Intervention Image can’t do it alone. It has to have a client-side component that allows the user to visually crop the image. For that there’s a jQuery plugin called cropper. I haven’t personally used it but the demo shows that the X and Y coordinates and the width and height can be determined using this library. So all you have to do is pass in those values to the server side and let Intervention Image do its thing.

Saving Images

Finally, you can commit the changes that you’ve made to the filesystem by using the save method. You don’t need to supply any arguments to it if you want to replace the original image. If you do not want that, then you can supply the path to the file where you want to save it. If you have a keen eye, you might have noticed that the original image was a .jpg image, and now its being saved as a .png image. Well that’s acceptable, Intervention Image automatically converts the image type for you. Lastly, the quality of the image can also be modified by passing in a second argument which has a value between 0 and 100. 100 being the same quality of the original image. In the example below, the quality is adjusted to 50% of the original one.

1
2
3
4
5
<?php
$img->save(); //replace the original image
$img->save('images/b.png'); //save to another file
$img->save('images/b.png', 50); //adjust quality of image
?>

Conclusion

That’s it! In this tutorial you’ve learned how to manipulate images in your PHP applications using the Intervention Image. As always, you have barely scratched the surface with this tutorial. There’s much more things that you can do with this library. I recommend you to check out the official website to learn more about it.

Validating Data With Respect Validation

| Comments

Data validation is an absolute need for every PHP application. This protects your app from security breaches caused by malicious user input. Good thing there’s not a shortage of data validation libraries available for PHP. And most frameworks (if not all) have it as part of their core functionalities. In this tutorial, I’ll be walking you through using the Respect Validation library for PHP. It’s one of the most complete validation libraries that I’ve seen. It can validate a whole range of data types such as numbers, strings, arrays, objects, date, banking data, phone numbers, emails and others.

Installation

You can install the library through Composer.

1
composer require respect/validation

Once that’s done, include the vendor autoload file and give an alias to the Validation class. This allows you to use the alias instead of the actual class name.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

use Respect\Validation\Validator as v;
?>

Validating Data

Now let’s take a look at some of the most common validators that you might want to use. All of the validators returns a boolean value, so if the data is valid it returns true, and if it’s not then it returns false. To validate a data, you first call the validator. Some validators allows you to specify the format in which the data should be and some does not. In cases that it allows you, simply pass in the format as the argument for that validator. Next, call the validate method and pass in the data that you want to validate.

Dates

To validate dates, you use the date validator. This accepts the date format as its argument. If you do not specify one, the default date format of Y-m-d is used.

1
2
3
4
<?php
$is_datevalid = v::date()->validate('2015-02-30'); //true
$is_datevalid = v::date('m-d-Y')->validate('2015-02-30'); //false
?>

If you haven’t noticed yet, one thing to note about date validation, is that it returns true even for a day that shouldn’t exist in a specific month. In the example above, the month february shouldn’t have a 30th day. If you use 32 or 33 for the day, it works fine since most of months have only 31 days.

Country Code

Validating country codes can be done by using the countryCode validator. On my testing, its only able to validate 2-character ISO country codes.

1
2
3
4
<?php
$is_validcountrycode = v::countryCode()->validate('PH'); //true
$is_validcountrycode = v::countryCode()->validate('PHL'); //false
?>

Between

The between validator allows you to validate if a specific value is between 2 values. It can validate strings, numbers and dates.

1
2
3
4
5
6
7
8
9
10
<?php
$is_between = v::string()->between('a', 'z')->validate('d'); //true
$is_between = v::string()->between('a', 'c')->validate('d'); //false

$is_between = v::int()->between(50, 90)->validate(20); //false
$is_between = v::int()->between(30, 60)->validate(31); //true

$is_between = v::date()->between('2015-03-25', '2015-04-30')->validate('2015-03-28'); //true
$is_between = v::date()->between('2015-07-12', '2015-10-30')->validate('2015-03-01'); //false
?>

Length

To validate if a string or array matches a specific length between a minimum and a maximum value, you can use the length validator. You can specify either of the minimum and maximum values if you don’t want to be specific.

1
2
3
4
5
6
7
<?php
$is_length = v::string()->length(10, 20)->validate('my-username'); //true
$is_length = v::string()->length(10, 20)->validate('my'); //false

$is_length = v::arr()->length(5, null)->validate(array('abc', 'def', 'ghi')); //false
$is_length = v::arr()->length(null, 3)->validate(array('abc', 'def', 'ghi')); //true
?>

Min and Max

The min and max validators allows you to check if an integer or date value is within the minimum or maximum value that you specify.

1
2
3
4
5
6
7
<?php
$is_min = v::int()->min(100)->validate(25); //false 
$is_min = v::int()->min(1)->validate(2); //true 

$is_max = v::date()->max('2015-07-27')->validate('2015-03-12'); //true 
$is_max = v::date()->max('2015-06-13')->validate('2015-08-29'); //false 
?>

Numbers

You can validate number values using the numeric, digit, and int validators. numeric is the generic number validator, it can accept integer, double or float values and even negative numbers. digit accepts whitespaces between integer values but it doesn’t accept float or double values. int accepts only integer values.

1
2
3
4
5
6
7
8
9
10
<?php
$is_numeric = v::numeric()->validate('55'); //true 
$is_numeric = v::numeric()->validate('99.9'); //true

$is_numeric = v::digit()->validate('45 3 330'); //true
$is_numeric = v::digit()->validate('7.9'); //false

$is_int = v::int()->validate('8.2'); //false
$is_int = v::int()->validate('709'); //true
?>

Domain

Domain names can be validated using the domain validator.

1
2
3
4
<?php
$is_domain = v::domain()->validate('github.com'); //true
$is_domain = v::domain()->validate('google.com.ph'); //true
?>

Bank

Bank information can also be validated. Currently, you can only validate bank accounts and bank identifier codes for Germany. And you have to install the bav Composer package to do that:

1
composer require malkusch/bav

Here are a few examples:

1
2
3
4
5
6
7
<?php
$is_bankaccount = v::bankAccount("de", "70169464")->validate("1112"); //true
$is_bankaccount = v::bankAccount("de", "70169464")->validate("1234"); //false

$is_bankaccount = v::bic("de")->validate("VZVDDED1XXX"); //true
$is_bankaccount = v::bic("de")->validate("VZVDDED1"); //true
?>

Alpha

If you want to restrict a string to only have letters, you can use the apha validator.

1
2
3
4
<?php
$is_alpha = v::alpha()->validate('abc 123'); //false
$is_alpha = v::alpha()->validate('abc def'); //true
?>

Alnum

You can validate alphanumeric characters (numbers and letters) using the alnum validator. You can group it

1
2
3
4
5
6
<?php
$is_alnum = v::alnum()->validate('batman 123'); //true
$is_alnum = v::alnum()->lowercase()->validate('batman 123'); //true
$is_alnum = v::alnum()->uppercase()->validate('batman 123'); //false
$is_alnum = v::alnum()->notEmpty()->validate('batman 123'); //true
?>

Email

Email addresses are validated using the email validator.

1
2
3
4
<?php
$is_email = v::email()->validate('not'); //false
$is_email = v::email()->validate('email@gmail.com'); //true
?>

Phone

Phone numbers that have 7, 10 or 11 digits in them can be validated.

1
2
3
4
<?php
$is_phone = v::phone()->validate('(072) 242 8084'); //true
$is_phone = v::phone()->validate('+639111111111'); //true
?>

Required

To set a specific data as required, you use the notEmpty validator.

1
2
3
4
<?php
$is_required = v::isNotEmpty()->validate(''); //false
$is_required = v::isNotEmpty()->validate('im not empty'); //true
?>

Chaining

As you have seen earlier, you can combine different validators together. Here are a few examples:

1
2
3
4
<?php
$is_alnum = v::alnum()->notEmpty()->validate('superman 456'); //true
$is_alnum = v::email()->notEmpty()->lowercase()->validate('superman456@gmail.com'); //true
?>

Validating an Array of Data

To validate an array of data or a form, you need to setup the rules for each field and add them in an array. You then loop through each item in the array and validate them one by one. In the example below, the check method is used instead of the validate method. This is because the validate method only returns a boolean value and not the actual error message. While the check method returns an exception which you can then get by calling the getMainMessage method in the exception that was returned. Lastly, use break to break the execution of the foreach loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$rules = array(
    'username' => v::string()->lowercase()->length(10, 20)->notEmpty()->setName('username'),
    'email' => v::email()->notEmpty()->setName('email'),
    'phone_number' => v::phone()->notEmpty()->setName('phone number')
);

$data = array(
    'username' => 'wernancheta',
    'email' => 'myemail@gmail.com',
    'phone_number' => '111'
);

foreach($data as $key => $value){

    try{
        $rules[$key]->check($value);
    } catch (\InvalidArgumentException $e) {
        echo $e->getMainMessage();
        break;
    }

}
?>

Conclusion

That’s it! In this tutorial you’ve learned how to use the Respect Validation library for PHP. Be sure to check out the official docs if you want to learn more. If you’re using Laravel, you might want to check out this article on Sitepoint: Validating your data with Respect Validation.

Why I Love Web Development

| Comments

It’s not very often that I reflect on why I love things. Why I Love Web Development is not a question I often ask myself. In this essay I’ll attempt to explore the why. I first started learning about Web Development when I was in College. Back then it was just another subject that I had to learn in order to finish my course. I never really thought that it would be the thing that puts money in my pocket 5 years later. I became a Web Developer. It’s very easy to get into Web Development. All you need is a computer, a text-editor and a browser. Just create an HTML file, put some styling into it, and then sprinkle some JavaScript to make things more interactive and you have a full-fledge web page. Of course you’ll need to install other things such as Apache, MySQL and PHP if you’re working on the back-end. But initially, Web Development is very accessible for beginners. With websites such as Code School, Pluralsight and Codeacademy it became even easier to get into https://www.codecademy.com/. Perhaps that’s the first thing that made me fall in love with Web Development. It’s easy to get into it. There’s also a plethora of information about it. Q&A websites such as Stackoverflow makes it really easy to solve problems in case you get stuck with something. All you really need to know is to know what to Google.

Web Development isn’t without its difficulties. If you’re a Web Developer you have to learn so many things. You have to consider a lot of things when it comes to your users. You need to be empathetic to their needs. That’s probably the reason why there are Web Designers, Front-end Developers, Back-end Developers, Devops and UX Designers. One person can’t really do it all. I’m not really one to talk because I’ve only been practicing Web Development as a Full-stack Developer. Which means that I take care of everything. Or not. I have to admit that I lack the qualities of a Web Designer. And when it comes to UX, I have a lot to learn. I primarily consider myself a Back-end Developer because that’s where my core skills are. But this doesn’t mean that I have to ignore learning things about design and how to make things more accessible. This doesn’t mean that I don’t need to make an effort no matter how little. Such as putting the alt attribute on images or sprinkling some aria-role attributes in my HTML code. Aside from that, you also need to think about performance. Not all users have a blazing fast internet connection with 10 GB/s download speed. But it doesn’t end there. As a developer you also need to think of the maintainability of your code. You need to think of the next person who’s going to end up maintaining your code. As a developer you have to make an effort on carefully naming things and structuring your code in such a way that things can easily be found. Your code should also be DRY. Which means that there should only be a single source of truth in your code. And avoid repeating things as much as possible. You need to think about the future. The dependencies you pull into your code. It’s always wise to pull in a third-party library to easily accomplish things that would be hard for you to implement on your own. But you also need to make sure that your code doesn’t break if this library gets updated.

The idea of creating something that didn’t previously exist. The joy of building something and seeing it come to life is what makes Web Development really awesome. You get to play around with shiny, new and cool stuff all the time. You get to learn something new every day. You get to work on side-projects and push it to Github and have other people use your work. That to me is fantastic.

The ability to see the world in a Programmer’s eyes. You begin to wonder how things are built. What technologies are behind it? How are things implemented?

The dread that you feel whenever a new JavaScript library comes out. And the fear that the shiny new thing that you’ve learned is replaced by that JavaScript library that came out.

The never-ending queue of articles that you think you have to read in order to keep yourself up to date.

The idea that you can reach a lot of people by just creating a single website. The idea that you can provide valuable information and make their life easier by using the thing that you created. The ability to empower people from a thousand miles a way and they don’t even know you. That to me is priceless.

Generating Fake Data in PHP With Faker

| Comments

In the good old days, I often test PHP applications by accessing it directly from the browser and input the data in the forms. Today, with the explosion of awesome PHP libraries you can now generate most kinds of data by using code alone. The data can then be directly inserted into the database. This reduces the need to input data directly into the app. In this tutorial, I’ll be walking you through Faker, a PHP library that generates fake data for you.

Installation

You can install Faker by executing the following command. Note that this requires you to have Composer installed.

1
composer require fzaninotto/faker

Concepts

Here are a few concepts that you need to remember before moving on.

  • generators – responsible for generating data.
  • providers – the data source for generators. Generators can’t really stand by themselves. Providers really shine on the localization feature of Faker. Real places, phone numbers in countries can be generated by Faker through the use of providers.
  • formatters – these are the properties that you can access from a specific generator. Examples include name, city, address, and phoneNumber.

Usage

To use Faker from your file, you need to include the vendor autoload file and create a new Faker instance.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

$faker = Faker\Factory::create();
?>

Localization

Since Faker is an open-source project that anyone can contribute to, lots of localized providers has already been added. You can take advantage of this by passing in the locale when you create a new Faker instance. For example, if you live in the Philippines:

1
2
3
<?php
$faker = Faker\Factory::create('en_PH');
?>

You can then generate an address in the Philippines by using the address formatter. Note that it’s only down to the city level. This means that the street and barangay are using the default providers.

1
2
3
<?php
echo $faker->address;
?>

Note that each provider doesn’t have generators for every possible formatter. For example, the Philippine provider has only generators for the Address and PhoneNumber. This means that you can only have localized values for those. All the other formatters will utilize the default ones provided by Faker. For a list of providers, check out this page in their Github repo.

Formatters

Here are the formatters that I commonly use in my projects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
//person
$faker->name;
$faker->firstName('male');
$faker->lastName;

//address
$faker->address;
$faker->streetName;
$faker->streetAddress;
$faker->postCode;
$faker->address;
$faker->country;

//company
$faker->company;

//date and time
$faker->year;
$faker->month; //number representation of a month
$faker->monthName;
$faker->timezone; //valid php timezone (http://php.net/manual/en/timezones.php)
$faker->time; //string time
$faker->dateTime; //datetime object
$faker->unixTime; //unix timestamp

//internet
$faker->email;
$faker->userName;
$faker->password;

//payment
$faker->creditCardType;
$faker->creditCardNumber;

//images
$faker->imageUrl(50, 60); //where width=50 and height=60
?>

Creating New Providers

If you want to create a provider for your own project, you can easily extend Faker. For example, if you want to generate random pokemon names. The first thing that you need to do is to declare the namespace in which the class belongs. Next, declare a new class and have it extend the faker provider base class. Inside the class, create an array of Pokemon names. Create a new function and call it pokemon, this is the function that will be called later on to generate a random pokemon name. To pick a random item from the array you created, use the randomElement function and then pass in the array which you want to use as the data source.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
namespace Faker\Provider;

class Pokemon extends \Faker\Provider\Base {

  protected static $pokemon = array(
    'Pikachu',
    'Bulbasaur',
    'Cubone',
    'Charizard',
    'Marowak',
    'Gastly',
    'Alakazam',
    'Arcanine',
    'Vaporeon',
    'Flareon',
    'Venusaur',
    'Wartortle'
  );

  public function pokemon(){
    return static::randomElement(static::$pokemon);
  }
}
?>

Save the file and name it Pokemon.php. You can save it any where in your project as long as you can easily reference it from your main file.

On your main file, include the vendor autoload together with the file that you’ve just created.

1
2
3
4
<?php
require_once 'vendor/autoload.php';
require_once 'Pokemon.php';
?>

Create a new faker generator. This is a bare bones generator with no providers assigned to it. So if you use $faker->name, all you get is an error.

1
2
3
<?php
$faker = new Faker\Generator();
?>

If you want to use the default providers, you can include them by calling the addProvider method and passing in a new instance of the provider that you want to include.

1
2
3
4
5
6
7
8
<?php
$faker->addProvider(new Faker\Provider\en_US\Person($faker));
$faker->addProvider(new Faker\Provider\en_US\Address($faker));
$faker->addProvider(new Faker\Provider\en_US\PhoneNumber($faker));
$faker->addProvider(new Faker\Provider\en_US\Company($faker));
$faker->addProvider(new Faker\Provider\Lorem($faker));
$faker->addProvider(new Faker\Provider\Internet($faker));
?>

To add the new Pokemon provider.

1
2
3
<?php
$faker->addProvider(new Faker\Provider\Pokemon($faker));
?>

Once that’s done, you can now call the new pokemon formatter.

1
2
3
<?php
$faker->pokemon; //marowak
?>

Integration with Your PHP Application

Most PHP frameworks today already comes with a database seeding feature. If you’re using Laravel, it has a database migration and seeding functionality. You can simply install Faker into your project, generate a new seeder and then use Faker inside the seeder. This allows you to seed your database with Fake data in a single command by using Artisan CLI. If your framework doesn’t include a seeding feature, you can use Phinx, a database-migration tool for PHP. This tool also allows you to create seeders for your database.

Conclusion

That’s it! In this tutorial, you’ve learned how to work with the Faker library to generate fake and random data for testing your PHP applications. Check out the official github page for more information regarding its usage.

Making HTTP Requests With Guzzle

| Comments

Most PHP applications today includes the ability to integrate with different web services such as Facebook, Twitter, Google, and other API’s. Thus the need for a library to ease the process of making HTTP requests to other servers. Most API’s already comes with their own clients for selected programming languages. These clients makes the interaction with their API’s easier. But oher services doesn’t offere any clients at all. This is where Guzzle comes in, a PHP library that allows you to easily make HTTP requests. In this tutorial, I’ll be walking you through this library.

Installation

You can install Guzzle through Composer by executing the following command.

1
composer require guzzlehttp/guzzle:~6.0

Usage

You can start using Guzzle by including the vendor autoload file then use the Client class in the GuzzleHttp namespace.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

use GuzzleHttp\Client;
?>

From there, you can create a new client. This accepts an array of arguments. The most important one is the base_uri, which is the base URL that will be used for each of the requests that you will make with this client. In the example below, the base URI is that of the Pokemon API, an API which allows you to get any data about Pokemon.

1
2
3
<?php
$client = new Client(['base_uri' => 'http://pokeapi.co/api/v1/']);
?>

To make an actual request to an endpoint, you can use the get method to make a GET HTTP request. To extract the response body, you have to call the getBody method in the response that was returned. Most API’s today returns a JSON string as their response. The Pokemon API is no exception. So you need to use the json_decode method and pass in the data. You can pass in true as the second argument to convert it to an array.

1
2
3
4
5
6
7
8
<?php
$response = $client->get('pokedex/1');
$data = $response->getBody();
$data = json_decode($data, true);
?>
<pre>
<?php print_r($data); ?>
</pre>

Here’s the output that you get when accessing the file from the browser. From this data, we know that the pokedex/1 endpoint returns all the pokemon that are currently existing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Array
(
    [created] => 2013-11-09T15:14:48.957604
    [modified] => 2013-11-09T15:14:48.957565
    [name] => national
    [pokemon] => Array
        (
            [0] => Array
                (
                    [name] => rattata
                    [resource_uri] => api/v1/pokemon/19/
                )

            [1] => Array
                (
                    [name] => charmander
                    [resource_uri] => api/v1/pokemon/4/
                )

            [2] => Array
                (
                    [name] => charmeleon
                    [resource_uri] => api/v1/pokemon/5/
                )

            [3] => Array
                (
                    [name] => wartortle
                    [resource_uri] => api/v1/pokemon/8/
                )

            [4] => Array
                (
                    [name] => blastoise
                    [resource_uri] => api/v1/pokemon/9/
                )

            [5] => Array
                (
                    [name] => caterpie
                    [resource_uri] => api/v1/pokemon/10/
                )

            [6] => Array
                (
                    [name] => metapod
                    [resource_uri] => api/v1/pokemon/11/
                )

            [7] => Array
                (
                    [name] => butterfree
                    [resource_uri] => api/v1/pokemon/12/
                )

            [8] => Array
                (
                    [name] => spearow
                    [resource_uri] => api/v1/pokemon/21/
                )

            [9] => Array
                (
                    [name] => kakuna
                    [resource_uri] => api/v1/pokemon/14/
                )

            [10] => Array
                (
                    [name] => beedrill
                    [resource_uri] => api/v1/pokemon/15/
                )
...

Note that it’s not only get method that you can do with Guzzle. Each HTTP methods have their equivalent method in Guzzle. So post, put and delete are all valid method names.

Before moving on, here’s another example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
$response = $client->get('pokemon/150');
$data = $response->getBody();
$data = json_decode($data, true);

$moves = array_filter($data['moves'], function($move){
    return $move['learn_type'] == 'level up';
});

$description_response = $client->get(str_replace('/api/v1/', '', $data['descriptions'][0]['resource_uri']));
$description_data = $description_response->getBody();
$description_data = json_decode($description_data, true);
?>
<div>
    <img src="<?= 'http://pokeapi.co/media/img/' . $data['pkdx_id'] . '.png' ?>" alt="<?= $data['name'] ?>">
    <h4><?= $data['name'] ?></h4>
    <p>
        <?= $description_data['description']; ?>
    </p>
    <div>
        <strong>Moves</strong>
        <ul>            
        <?php
        foreach($moves as $move){
        ?>
        <li>
            <?= $move['name']; ?>
        </li>
        <?php
        }
        ?>
        </ul>
    </div>
</div>

In the code above, 2 GET request were used to get all the data that is needed for the final output. First, the pokemon endpoint is used to get the details of a specific pokemon. Second is the request for getting the description of the pokemon. In order to extract the moves, the array_filter function is used. The condition is to select only moves that have been learned through level up. In order to get the endpoint for getting the description, the str_replace function is used to replace a part of the base uri in the resource uri that was returned. Since the resource uri already has the /api/v1/ in the beginning. Guzzle would end up making a request to the following URL if that string isn’t replace with an empty one.

1
http://pokeapi.co/api/v1//api/v1/description/150

The output is going to look like this.

mewtwo

Finally let’s take a look at how to do a POST request with Guzzle. For that let’s try to submit a post to Facebook using Facebook API. To do that, declare a new client using the https://graph.facebook.com/ as the base_uri. Posting to facebook requires the access_token, message and an optional link. Call the post method and pass in me/feed as the first argument. This is the endpoint for posting to facebook. The second argumment is an array containing the data that you want to submit. In Guzzle, the data should be contained within the query item. You can then call getBody on the response to get the response body. This should return the ID of the post that was created.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$client = new Client(['base_uri' => 'https://graph.facebook.com/']);

$post_data = array(
    'access_token' => 'YOUR-FACEBOOK-ACCESS-TOKEN',
    'message' => 'testing',
    'link' => 'http://wern-ancheta.com/'
);


$res = $client->post('me/feed', array(
    'query' => $post_data
));

$response_body = $res->getBody();
$response_body = json_decode($response_body, true);
?>

Conclusion

That’s it! In This tutorial, you’ve learned how to make HTTP requests with the Guzzle library. There’s so much more you can do with Guzzle, so be sure to check out their official docs if you want to learn more.

Stalking the Programmer Way With Clearbit’s Person API

| Comments

In this tutorial, I’ll be showing you can programatically find out information about any person using their email. You can do that by using the Clearbit Person API.

In order to use the Person API, you first have to create your Clearbit account. After creating your account, you’ll be assigned with an API key which you can use for making requests to their API.

If you’re on Ruby, Node or Python you can search for the Clearbit client for each of those platforms from their Github page. Just search for ‘clearbit-’ followed by the platform. So if you’re on Ruby, then you search for ‘clearbit-ruby’. You can then install the client on your machine and follow the examples provided in the official documentation.

At the time of writing of this article, there’s still no client available for PHP. But you can use Guzzle to easily make requests to their API. You can install Guzzle via Composer by executing the following command.

1
composer require guzzlehttp/guzzle:~6.0

Once that’s done, you can include the vendor autoload file in your test file and then create a new instance of the Guzzle client. Use http://person.clearbit.com/v1/ as the base for all your requests.

1
2
3
4
5
<?php
require_once 'vendor/autoload.php';

$client = new GuzzleHttp\Client(array('base_uri' => 'http://person.clearbit.com/v1/'));
?>

To request the data of a specific person, you can pass their email after the people/email endpoint. Here’s an example.

1
2
3
4
5
6
7
8
9
<?php
$response = $client->get('people/email/ancheta.wern@gmail.com', array('auth' => array(
        'YOUR-CLEARBIT-API-KEY', ''
    )));
$res = json_decode($response->getBody(), true);
?>
<pre>
    <?php print_r($res); ?>
</pre>

Clearbit uses basic authentication. The API key acts as the username so the password should be left blank.

It would then return the following output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Array
(
[id] => c29c2e9f-d082-4525-8dd3-1291835bf834
[name] => Array
    (
        [fullName] => Wern Ancheta
        [givenName] => Wern
        [familyName] => Ancheta
    )

[email] => ancheta.wern@gmail.com
[gender] => 
[location] => Philippines
[geo] => Array
    (
        [city] => 
        [state] => 
        [country] => PH
        [lat] => 12.879721
        [lng] => 121.774017
    )

[bio] => JavaScripter, PHP Junkie, Anime Fanatic, Pokemon Master, Supernatural Enthusiast
[site] => http://wern-ancheta.com
[avatar] => https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/c29c2e9f-d082-4525-8dd3-1291835bf834
[employment] => Array
    (
        [name] => 
        [title] => 
        [domain] => 
    )

[facebook] => Array
    (
        [handle] => vern.ancheta
    )

[github] => Array
    (
        [handle] => 
        [id] => 
        [avatar] => 
        [company] => 
        [blog] => 
        [followers] => 
        [following] => 
    )

[twitter] => Array
    (
        [handle] => Wern_Ancheta
        [id] => 283769265
        [bio] => JavaScripter, PHP Junkie, Anime Fanatic, Pokemon Master, Supernatural Enthusiast
        [followers] => 330
        [following] => 961
        [statuses] => 7402
        [favorites] => 356
        [location] => Philippines
        [site] => http://wern-ancheta.com
        [avatar] => https://pbs.twimg.com/profile_images/2585189311/7q7dmz2h78lv32f8tw78.jpeg
    )

[linkedin] => Array
    (
        [handle] => 
    )

[googleplus] => Array
    (
        [handle] => 
    )

[angellist] => Array
    (
        [handle] => 
        [id] => 
        [bio] => 
        [blog] => 
        [site] => 
        [followers] => 
        [avatar] => 
    )

[klout] => Array
    (
        [handle] => 
        [score] => 
    )

[foursquare] => Array
    (
        [handle] => 
    )

[aboutme] => Array
    (
        [handle] => 
        [bio] => 
        [avatar] => 
    )

[gravatar] => Array
    (
        [handle] => zenonn
        [urls] => Array
            (
                [0] => Array
                    (
                        [value] => http://kyokasuigetsu25.wordpress.com
                        [title] => Data Integrated Entity Blog
                    )

                [1] => Array
                    (
                        [value] => http://wernancheta.wordpress.com
                        [title] => Wern Ancheta Web Development Blog
                    )

                [2] => Array
                    (
                        [value] => http://wernancheta.carbonmade.com
                        [title] => Wern Ancheta Portfolio
                    )

            )

        [avatar] => http://2.gravatar.com/avatar/717bcde740783a83a168468df0dbbb75
        [avatars] => Array
            (
                [0] => Array
                    (
                        [url] => http://2.gravatar.com/avatar/717bcde740783a83a168468df0dbbb75
                        [type] => thumbnail
                    )

                [1] => Array
                    (
                        [url] => http://0.gravatar.com/userimage/29616243/2e8d74c1260a1c180328ea6317ebb8e0
                        [type] => 
                    )

            )

    )

[fuzzy] => 
)

As you can see, it’s not very complete. It has left out my Github, LinkedIn, GooglePlus and FourSquare profiles. It doesn’t have one for Instagram as well. Nevertheless, this API proves to be a good resource if you want to get data about a specific person.

If you want to update your own data, extract the ID that clearbit has assigned to your profile and then use it on your request. Here’s an example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'http://person.clearbit.com/v1/']);
$response = $client->post('people/YOUR-CLEARBIT-ID/flag',
            array('auth' => array(
                'YOUR-CLEARBIT-API-KEY', ''
            ),
            'form_params' => array(
                'foursquare' => array('handle' => 'wern_ancheta'),
                'googleplus' => array('handle' => '+WernAncheta'),
                'github' => array(
                    'handle' => 'anchetaWern'
                ),
                'gender' => 'male',
                'linkedin' => array('handle' => 'wernr'),
                'gravatar' => array('handle' => 'vernancheta')
            )
        )
);
$res = json_decode($response->getBody(), true);
echo $response->getStatusCode(); //200
?>

Note that your data won’t be immediately update. This is good since the update must be reviewed by an actual human so that not just anyone can mess with your data.

A Whirlwind Tour of Web Developer Tools: Linting

| Comments

Yo! It’s been a while but I’ve decided to continue this series on A Whirlwind Tour of Web Developer Tools. For those who don’t know, I started this series a year ago but then I got so busy with work and I became an author at Sitepoint. So you can only count the number of in-depth tutorials with your fingers. But I quit my job and now I have a lot of free-time. That is why I no longer have any excuse not to continue what I started.

Ok enough with the life update. Now let’s move on to the main topic of this article. This is part eight of the series on Web Developer Tools where I’m going to walk you through linting. Linting is the process of running a program that will check the quality of code in order to avoid any potential errors. Take for example the following code:

1
2
3
4
5
6
function main(){
  if(x == y){
    return 'Hello, World!'
  }
  return 'Hello';
}

By looking at the code, you can immediately see that x and y hasn’t been defined. The semicolon is also missing from the first return statement. But if add this function to a JavaScript file, you will see that it doesn’t actually cause any errors until you add the code that will call the function. Only then will you realize that x and y hasn’t been defined. But JavaScript doesn’t actually complain if you miss a semicolon or two so the first return statement won’t probably cause any errors. This is because of the automatic semicolon insertion in JavaScript. I know the example that I gave is a bit contrived but you get the point. As developers we sometimes miss the obvious things such as defining a variable or putting a semicolon. That is why there are tools to help us avoid making these kinds of mistakes. Linters are one of those. In the world of web development there are a bunch of tools which can be classified as linters. I’m going to walk you through some of those in this tutorial.

Markup Validation Service

The markup validation service by the World Wide Web Consortium allows developers to check the validity of the HTML code that they’ve written. It uses the doctype defined at the very top of the document as a basis for which specific rules to use for checking the code. You can supply a URL, upload a file or directly input the HTML code that you want to check. Here’s an example:

w3c validator

As you can see from the screenshot, it gives you three types of feedback: info, warning and error. Info gives you general information about the page. Warnings are messages telling you that you can do better. Or something could be improved. In the example above it says that the document uses unicode private use areas. Which is basically another way of saying that undefined unicode characters shouldn’t be used in publicly available documents. Lastly there’s the error. These are messages that tells you to fix something because it might cause problems to the users of your website. In the example above, it’s saying that an alt attribute should always be defined, except in specific conditions. And then it points out to the SVG logo of the website which should probably have an alt assigned to it. This is important because some users might be partially disabled (color-blind, partially blind, etc.) might be using a screenreader to interact with your website. And the value that you have placed in the alt attribute is read out by the screenreader. If there’s nothing there then the user won’t be able to know what he’s currently focusing at.

HTMLHint

HTMLHint is a linter for HTML code. Unlike the markup validation service, this allows you to specify what specific validation rules are to be used to check your HTML code. For example you can specify that all tags should be in lowercase. Or that in every file, an ID can only be used once. Here’s an example:

htmlhint

HTMLHint gives you feedback on which specific line has problems in it. And if you hover over the line number, you will see what the specific error is. In the example above you can see that the errors are:

  • the id a_unique_id has been used twice. It doesn’t matter that the elements used are different as long as an ID is used more than once, it triggers the error on the lines in which the ID is used for the second time.
  • the div with the ID of a_unique_id hasn’t been closed. Note that this doesn’t get triggered on the line where the tag hasn’t been closed. Instead it gets triggered on the nearest closing tag which doesn’t have a pair.

At the bottom part of the website, you can check or uncheck rules depending on what you’d like to apply. There are are a number of rules you can choose from and the naming is pretty self-explanatory so I won’t be delving into that.

CSSLint

CSSLint as the name suggests, is a linter for CSS code. Just like HTMLHint it allows you to specify which validation rules you’d like to apply for the checking of your CSS code. With CSSLint there are mostly warning rules but you can trigger errors as well. Such as when a specific rule is empty, or when using unknown CSS properties, or disallowing duplicate one’s. Warning rules on the other hand requires you to add fallback colors if you’re using hsl, rgba, rgb, or hsla to specify colors. Older browsers might not support those methods of specifying colors so you’ll have to provide a fallback in hexadecimal format. Another example is disallowing units for 0 values. This is mostly for performance benefits. Here’s an example CSS code that I’ve checked with CSSLint:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
body {
    font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
    padding: 0;
    margin: 0;
    height: 100%;
    width: 100%;
}

#settings-button {
    float: right;
    margin-top: 20px;
    margin-right: 20px;
}

h1 {
    padding-left: 40px;
    display: inline-block;
}

#message {
    padding: 20px 40px;
    background: #64CF49;
}


#sidebar {
    width: 20%;
    float: left;
    background-color: #67B6DA;
    position: fixed;
    height: 100%;
}

#items-container {
    width: 80%;
    float: left;
    position: relative;
    margin-left: 20%;
    background-color: #F7F7F7;
}

ul li {
    list-style: none;
}

#sidebar h3 {
    border-bottom: 3px solid;
    padding: 0;
    padding-left: 30px;
}

#types li {
    padding: 10px 30px;
}

ul#types {
    padding: 0;
    font-size: 15px;
}

#types li a {
    text-decoration: none;
    color: #575757;
}

#items {
    padding: 0 20px;
}

#items li a {
    text-decoration: none;
    color: #3A3A3A;
    display: inline-block;
}

#items li {
    padding: 20px;
}

#items li:hover {
    background-color: #DFDFDF;
}

.item-info {
    display: inline-block;
    width: 100%;
    font-size: 15px;
    color: #8A8A8A;
    margin-top: 5px;
}

And then it showed me the following feedback:

csslint

As you can see I’ve used a lot of ID’s in this css file so CSSLint is complaining that I shouldn’t use ID’s. This is mainly because CSSLint have this idea that ID’s are completely unique and therefore there’s no room for reuse. CSSLint advocates the use of OOCSS (Object-oriented CSS) whose main principle is the reusability of code by means of using objects.

Another warning is the use of overqualified selectors:

1
2
3
ul#types{
    ...
}

It’s saying that just using #types would suffice.

The last type of warning is the heading should not be qualified warning:

1
2
3
#sidebar h3 {
    ...
}

This is because headings are considered as top-level styles. This means that you shouldn’t define their styles under a specific element. Because their appearance should be consistent throughout the entire website. Note that this is not saying that headings cannot be nested under a specific element. You can do that but when you’re declaring their styles it should be just on its own so that you can ensure that they look the same throughout the whole website.

JSHint

JSHint helps to detect errors and potential problems in your JavaScript code. It checks for undefined variables, the use of eval (we all know that eval is evil right?), unused variables and many others. In the JSHint website you can configure which rules to apply by clicking on the configure link. Here’s an example of how it works:

jshint

As you can see it provides you with some code metrics. It tells you how many functions has been defined, how many variables are not defined and how many are not used.

It also tells you the cyclomatic complexity of the largest functions. In case you’re wondering, cyclomatic complexity is just a fancy term for the complexity of a specific program. You can see that the cyclomatic complexity of the largest function that I’ve defined is 2. And the median (average) complexity of all the functions in the file is 1.5. People generally say that a cyclomatic complexity of 0 to 5 is fine. But if you get around 6 or more then you should consider refactoring your code.

Another warning that you can see in the example is the missing “use strict” statement. This is a way of telling the browser to use strict mode. I haven’t really dived into strict mode yet but the main idea is that adding this literal expression at the very top of each JavaScript file and at the very top of each function makes the browser complain more about your code. Take for example the following code:

1
2
x = "y"; //browser: sweet!
console.log(x);

Without invoking strict mode, the browser would happily execute this piece of code for you. But with strict mode it will complain that you haven’t defined x yet.

1
2
3
"use strict";
x = "y"; //browser: Uncaught ReferenceError: x is not defined
console.log(x);

Command Line Tool

HTMLHint, CSSLint, and JSHint can all be used through the command line. We’re going to take a look at how to do that in this section.

The first thing that you need to do is to install node.js and npm. But we’re not going to go through that here because I previously mentioned it in my article on package managers. Go ahead and check that out if you don’t already have node.js and npm installed.

Once you’ve installed node.js and npm, you can now install htmlhint, csslint, and jshint using npm:

1
npm install -g htmlhint csslint jshint

You can now immediately use them right after the installation is complete:

1
2
3
htmlhint index.html
csslint style.css
jshint main.js

Note that each of these tools already comes with default options. So if you were to execute each of the commands above, you will most likely get a warning or an error if your code is already complex enough. But you can also specify which rules to apply by creating a configuration file inside of your project directory.

For HTMLHint the configuration file that you have to create is .htmlhintrc and it looks something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
    "tagname-lowercase": true,
    "attr-lowercase": true,
    "tag-pair": true,
    "doctype-first": true,
    "tag-self-close": true,
    "attr-no-duplication": true,
    "attr-value-double-quotes": true,
    "attr-value-not-empty": false,
    "title-require": true,
    "id-unique": true,
    "inline-style-disabled": true,
    "inline-script-disabled": true,
    "doctype-html5": true,
    "alt-require": false
}

You can find the rules that you can specify in this page.

Here’s the HTMLHint cli-tool in action:

htmlhint-cli

And here’s the file that I checked:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>

</head>
<body>
    <div>
        <p id="boom"></p>
        <span id="boom"></span>
        <STRONG></STRONG>
        <strong></strong>
        <span>
        <i data href=fldsfl BOOM="bam!" style="color:red;"><b>dds</b></i>
        <div>
    </div>
</body>
</html>

For CSSLint it’s .csslintrc and it looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "adjoining-classes": false,
  "box-sizing": false,
  "box-model": false,
  "compatible-vendor-prefixes": false,
  "floats": false,
  "font-sizes": false,
  "gradients": false,
  "important": false,
  "known-properties": false,
  "outline-none": false,
  "qualified-headings": false,
  "regex-selectors": false,
  "shorthand": false,
  "text-indent": false,
  "unique-headings": false,
  "universal-selector": false,
  "unqualified-attributes": false
}

Note that I’ve pick up that configuration straight from bootstrap’s .csslintrc file. You can find the rules for CSSLint in this page.

Here’s CSSLint’s cli-tool in action:

csslint-cli

Here’s the stylesheet that was checked:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
body {
    font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
    padding: 0;
    margin: 0;
    height: 100%;
    width: 100%;
}

#settings-button {
    float: right;
    margin-top: 20px;
    margin-right: 20px;
}

h1 {
    padding-left: 40px;
    display: inline-block;
}

#message {
    padding: 20px 40px;
    background: #64CF49;
}


#sidebar {
    width: 20%;
    float: left;
    background-color: #67B6DA;
    position: fixed;
    height: 100%;
}

#items-container {
    width: 80%;
    float: left;
    position: relative;
    margin-left: 20%;
    background-color: #F7F7F7;
}

ul li {
    list-style: none;
}

#sidebar h3 {
    border-bottom: 3px solid;
    padding: 0;
    padding-left: 30px;
}

#types li {
    padding: 10px 30px;
}

ul#types {
    padding: 0;
    font-size: 15px;
}

#types li a {
    text-decoration: none;
    color: #575757;
}

#items {
    padding: 0 20px;
}

#items li a {
    text-decoration: none;
    color: #3A3A3A;
    display: inline-block;
}

#items li {
    padding: 20px;
}

#items li:hover {
    background-color: #DFDFDF;
}

.item-info {
    display: inline-block;
    width: 100%;
    font-size: 15px;
    color: #8A8A8A;
    margin-top: 5px;
}

Lastly there’s jshint. Here’s a sample .jshintrc file which I’ve taken from CSSLint. CSSLint is basically written in JavaScript that’s why it has its own .jshintrc file to help the developers in checking their code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    "camelcase": true,
    "curly": true,
    "eqeqeq": true,
    "es3": true,
    "forin": true,
    "immed": true,
    "indent": 4,
    "latedef": true,
    "newcap": true,
    "noarg": true,
    "noempty": true,
    "nonbsp": true,
    "quotmark": "double",
    "strict": true,
    "undef": true,
    "unused": true
}

You can find a list of options here.

And here is JSHint’s cli tool in action:

jshint-cli

With this script file being checked:

1
2
3
4
5
6
7
"use strict";
x = "y";
console.log(x);

function beam(){
    return x + u;
}

Build Tool Integration

Ok so we have a slight improvement over just copying and pasting the code that we want to check in the HTMLHint, CSSLint, and JSHint website. But wouldn’t it be great if we don’t need to execute the command every time we need to check? And in real-world projects you would most likely have multiple css, JavaScript and HTML files. So executing the commands for each of those files would be too troublesome and time-consuming. That is where build tools comes in. Luckily I’ve already done an article specifically about build tools so if you’re new to it then be sure to check that out. Then you can go back to this article once you have an idea how to use a build tool.

Ok so you’re back. Hopefully you’ve learned all about Grunt and Gulp. In this article we’ll be using Gulp and the Gulp plugins for HTMLHint, CSSLint and JSHint. You can install those with the following command:

1
npm install gulp gulp-htmlhint gulp-csslint gulp-jshint

Optionally you can also install the formatters to make the reports more beautiful.

1
npm install htmlhint-stylish jshint-stylish

Note that there’s also a package called csslint-stylish but it currently doesn’t work with Gulp. If you’re reading this article at a later time be sure to check out that page and see if it already works for Gulp.

The next step is to create a gulpfile.js file in the root of your project directory and then add the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var gulp   = require('gulp');

var htmlhint = require("gulp-htmlhint");
var csslint = require('gulp-csslint');
var jshint = require('gulp-jshint');

gulp.task('lint_html', function(){
    gulp.src("*.html")
        .pipe(htmlhint())
        .pipe(htmlhint.reporter("htmlhint-stylish"));
});

gulp.task('lint_css', function(){
  gulp.src('*.css')
    .pipe(csslint())
    .pipe(csslint.reporter());
});

gulp.task('lint_js', function(){
    gulp.src('*.js')
        .pipe(jshint())
        .pipe(jshint.reporter("jshint-stylish"));
});

gulp.task('watch', function() {
    gulp.watch('*.html', ['lint_html']);
    gulp.watch('*.css', ['lint_css']);
    gulp.watch('*.js', ['lint_js']);
});

Like I said earlier, I won’t go deep into this because I’ve already written a whole article on Build Tools. Basically what this file does is to declare all the task that we want to perform with Gulp. We have four tasks in total, one for each linter and one for watching files in a specific directory. The only task that we need to execute is the last one:

1
gulp watch

What this does is to watch all the HTML files and then execute the HTML Linter. The same is true with the other file types. The linter for each specific file type is executed once you save a file. So if you press ctrl + s on your keyboard, the task is immediately executed. What you can do is you can either switch windows (alt + tab) or put the command line window and your text-editor side by side so you get instant feedback on your code.

Text-editor Integration

For the final part we’re going to look at how to integrate the linting tools in the text-editor. I’m a Sublime Text user so I’ll be using it for the examples. But if you’re using another text-editor or IDE be sure to check out if these tools are also available.

The first thing that you need to do is to install the SublimeLinter plugin with Sublime Package Control.

Once installed, determine where HTMLHint, CSSLint, and JSHint are installed in your computer. In Ubuntu you can do something like:

1
2
3
which htmlhint
which csslint
which jshint

That will return the path to the executable file. For me it was /home/wern/.nvm/v4.0.0/bin/csslint for csslint. Note that csslint in that path is the executable file itself. So the path that you actually want is /home/wern/.nvm/v4.0.0/bin. It returned the same path for HTMLHint and JSHint for me so I only need that one path. Once you’ve found it, go ahead and copy that path.

Next open Sublime Text, click on the preferences menu > package settings > SublimeLinter > Settings – User. This opens the user configuration file for SublimeLinter. Add the following into it and then save.

1
{}

Open the file again by going through the same steps above. This time Sublime Text has already added the default configurations in there. What you need to do now is to look for the paths object and under your current operating system at the path to where the HTMLHint, CSSLint and JSHint executables are. Because I’m using Ubuntu I had to put it inside linux object.

1
2
3
4
5
6
7
"paths": {
    "linux": [
        "/home/wern/.nvm/v4.0.0/bin"
    ],
    "osx": [],
    "windows": []
},

Once you’re done, save the file then restart Sublime Text (close it and open again).

Open the Sublime Text console by pressing ctrl + ` then look for something similar to the following:

1
2
3
SublimeLinter: htmlhint activated: /home/wern/.nvm/v4.0.0/bin/htmlhint
SublimeLinter: jshint activated: /home/wern/.nvm/v4.0.0/bin/jshint
SublimeLinter: csslint activated: /home/wern/.nvm/v4.0.0/bin/csslint

This tells you that SublimeLinter has successfully picked up the paths to where the linters are installed. If you’re seeing that then you’re good to go, if not then be sure to check if the path that you’ve supplied really contains the executable code for each of those linters.

Here are some screenshot that shows the linters in action:

htmlhint text editor

csslint text editor

jshint text editor

The yellow dots indicates warnings, while the red dots indicate errors. If you move your cursor over to the line where a dot is, you can see the actual message on the status bar (bottom left corner of the screen). Pretty sweet right?

Conclusion

That’s it! In this article you’ve learned how to use some of the tools that you could use to help you with determining potential problems in your HTML, CSS and JavaScript code. You’ve also learned how to integrate this into your workflow by making use of the command-line tool or the text-editor integration.

Resources

A Developers New Years Resolution

| Comments

It’s 2016. A brand-new year is upon us. And this is the time of the year when people usually set goals for the new year. While most other folks have new year’s resolution for their real life, In this article I’ll be sharing some of my new year’s resolution as a developer.

Generate Passive Income

The idea of generating a passive income has really enticed me in the past but it’s only this year that I’ve thought about it seriously. For developers one way of generating passive income is through marketplaces like Themeforest and CodeCanyon. All you have to do is build something useful and you can sell it on the platforms that I’ve just mentioned. I’ve already created an account on CodeCanyon, set it up and read their terms. All that’s left for me to do is to build something and submit it for review so that people can find it.

Continue What I’ve Started

I have a bunch of projects on Github. Some might not already work. Some lacking in documentation. This year I’ll continue every project that I started. Or at least mention that I won’t already be doing active development for projects that I’m no longer interested in pursuing.

I have also a blog series that I started back in 2014 which I called: A Whirlwind Tour of Web Developer Tools, I’m planning to start that up again this year.

Be More Picky

I read a lot. In fact I’ve created a website that curates all the news from sources that I want. Usually these are from the developer newsletters, twitter users, and websites that I follow. But I’m still subscribed to the newsletters which I have used as the news item source. So it still gets the better of my time when I receive a new issue. My plan is to unsubscribe to all of those newsletters and just stick to using the website myself. This is so that I don’t accidentally engage to some content. Or click on a link and not actually reading what’s in there. With the new setup I can actually just visit the website if I really want to read something and not when I receive a new issue of a newsletter.

The second step after unsubscribing to all newsletters is to actually pick only what I really want to read. If its a tool that I can use in the future, then I save it on my delicious account. If its an article which I want to go back to in the future then I save it on Pocket.

The third step is to actually read what’s really important or at least something that I really want to read. Of course this can’t be determined by merely looking at the title so the article has to be scanned first and then determine if it’s really relevant.

Of course this goes with all the other content that I’m consuming and creating. So movies, anime shows, personal projects, blog posts should go through a tight consideration before I actually engage on it.

Be More Healthy

Developers have a sedentary lifestyle by nature. Just sitting on a chair coding all day. That’s no good so here are the steps that I’m planning to implement to be more healthy.

  • Indoor exercise in the morning. Intense outdoor exercise in the weekends.
  • Use the standing desk at least one hour in the morning and one hour in the afternoon.
  • Eat less rice.
  • Eat more fruits and vegetables. There should be at least one meal per day where I eat a decent amount of those.
  • Get more sunlight.
  • Sleep more.
  • Be more concious about my posture.

Engage More in the Community

  • I’ll start by creating videos on Youtube showing a specific technology, tool or methodology regarding web development. I’ve already started it the previous year by uploading some of my flipped classroom videos that I’ve used in my class in the school where I teach.
  • Comment on other developers blog posts, or talk to them on twitter.
  • Answer questions on Stackoverflow.
  • Attend local developer meetups.
  • Contribute to open-source projects.

Use Tools

I’ve been pretty much avoiding the use of tools in my day to day job as a developer. I still use plain css instead of Less, Sass, Stylus or {insert your css preprocessor of choice here}. I still don’t use Grunt, Gulp, Brocolli, Carrots, Eggplant, {insert your build tool of choice here} for every project (note: there’s no carrots or eggplant yet but someone might create it after this). I’ve been avoiding the use of tools because I just want to get started with a project fast. Installing a bunch of tools and setting them up before I can start coding is a pain. The only tools that I currently use are the following:

  • Composer
  • Bower
  • npm

Simply because you can’t install anything without those.

This year I’ll start by learning how to use Yeoman so I can easily setup all the things that I need for a project. And then learn how to use a css preprocessor, Gulp to process the project assets, JSLint to check the quality of my JavaScript code. And then in the back-end use PHPUnit for unit-testing. And lastly use a continuous integration server such as Jenkins to automatically run unit tests so that I immediately know if a specific code is still working or not.

Build More Cool Shit

Pardon the language but developers are commonly foul-mouthed right? Anyway, what I mean by build more cool shit is to create stuff that I can be proud of. I’d also like to build IOT (Internet of Things) projects. And with the birth of the RaspberryPi zero it just got more easy. Though I’m yet to order one because the stock is always zero. I should have ordered one when I first heard about it. Now people are ordering it non-stop. Who wouldn’t right? RaspberryPi zero is only five fucking dollars.

Learn a New Language, Framework, Tool, Methodology

  • Language: Python – If I am to build stuff with RaspberryPi I need to learn to code in Python. I also want to leap from the hybrid app bandwagon and go full native so I’ll have to learn (or rather re-learn) Java. This is simply because apps built with Hybrid App Framework such as Cordova performs poorly on my old android phone. Maybe I just need a new phone but I’ll go ahead and blame it to programming.
  • Framework: Symfony – I’m basically a Laravel guy so for a change I pick Symfony.
  • Tools: CI Server, PHPUnit, Gulp, Sass, ReactJS
  • Methodology: I’m still not sure. But I’ll probably try to learn some of the most popular design patterns in JavaScript and PHP.

Get Better at What I Do

No matter how good you are at something there’s always room for improvement, there’s always another way for doing things twice as easy or efficient. So the plan for 2016 is to look for ways to improve my current development workflow. Like I said earlier I’m a Laravel guy so I’ll start by examining my current Laravel workflow and see what I can improve.

Invade Other Fields

I’ve been really interested in UX because I know it will be helpful for me as an all-around developer. When I say all-around it means I’m the one doing the server setup up to deployment and anything between those two. I’m pretty much a one-man band in all the projects that I’ve built so far. No devops, no designer, no nothing.

Another field that I’d like to look into is SEO. Who wouldn’t want to have their website more findable?

That’s it! How about you? What’s your plan for 2016?