September 12, 2017

My First Hackathon

Last Wednesday, I participated on IAK Hackathon, held by Indonesian Google Developer Group. It was first Hackathon.

I was surprised that more than 50% of the participants are much younger than me. Luckily my teammate, was not so distant in age with me. It was a fun event, where we got the chance to get a bunch of cool advice and perspectives on developing attractive application from an experienced mentor, especially in a Hackathon where time is not a luxury that we had.

Since the theme of the Hackathon was "Sports and Healthy Lifestyle", my team developed an Android application called "MamaOlga" which in Indonesian stands for "Mari-mari Olahraga" (Eng: Let's do sport together). The app basically searches people who has common sports interest in nearby location.

Unfortunately I didn't got the chance to code the Android part, instead, as my specialty, I did the REST API backend. With Laravel. With Passport. I would like to make a special article about providing a usable RESTful API, with clean JSON responses for Android apps someday. But in this article, I'm only going to share the full source code.

So, here it is:
https://drive.google.com/file/d/0BwO5-mGH9haoSXUxNXU2cDY1Nm8/view?usp=sharing

And here is the presentation slides:
https://docs.google.com/presentation/d/1Be9Rpj2nX0fqFjCockxSlbd5HM8G1nbNUIMcXMN8JJI/edit?usp=sharing

The flow of the REST API is as follow:

  1. Client requests for an access token by submitting app client_id, and client_secret. App users mus also provide username and password.
  2. API respond with an access token if the credentials on step 1 is correct.
  3. The access token can then be used to fetch other data by requesting to several endpoints, such as:
    • Get users nearby
    • Get joined chat groups
    • Get chat threads based on group
    • Invite someone to private chat
    • Get chat threads on a private channel

Perhaps someone would develop this REST API even further, or as an example to your project or your Hachaton ^_^.

Please leave a comment below if you have any question, or if you want to share your first Hackathon experience.

August 13, 2017

Git Notes

441  git init
  442  git config user.name myusername
  443  git config user.email my@gmail.com
  444  git config user.name
  445  git config user.email
  446  git remote add origin https://github.com/myusername
  452  git pull origin master
  453  git add .
  454  git commit -m "Inisialisasi project"
  455  git push origin master

VueJS Example

Just an example, not a full article

<!DOCTYPE html>
<html>
<head>
 <title></title>
 <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
 <div id="app">
  <!-- Button trigger modal -->
  <button id="validate-trigger-1" type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
   Launch demo modal
  </button>

  <button id="validate-trigger-2">Validate</button>

  <!-- Modal -->
  <div id="myModal" class="modal fade" tabindex="-1" role="dialog">
   <div class="modal-dialog" role="document">
    <div class="modal-content">
     <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      <h4 class="modal-title">Pilih BBB</h4>
     </div>
     <div class="modal-body">

    <?php /* {{-- Start milih --}} */ ?>
      <select v-on:change="milih_a" v-model="pil_a" name="bbb" id="bbb">

      <option value="">-- Pilih Salah Satu --</option>
       <option v-for="pil in pilihan" :value="pil.value">{{pil.option}}</option>
      </select>

      <div v-if="pil_a != ''">
       <select v-on:change="milih_jk" v-model="pil_jk" name="jkjkjk" id="jkjkjk">
        <option value="">-- Pilih GGG --</option>
        <option v-for="k in jk" :value="k.value">{{k.option}}</option>
       </select>
      </div>

      <div v-if="pil_jk != ''">
       <select v-model="pil_d" name="ppp" id="ppp">
        <option value="">-- Pilih PPP --</option>
        <option v-for="d in dikum" :value="d">{{d}}</option>
       </select>
      </div>

      <div v-if="pil_d != ''">
       <input type="" name="jjj" id="jjj" placeholder="Isi dengan jjj">
       <div v-if="pil_a == 'ugl'">
        <select v-model="pil_skill" name="kkk" id="kkk">
         <option value="">-- Pilih KKK --</option>
         <option v-for="s in kkk" :value="s">{{s}}</option>
        </select>
       </div>
       <div v-if="pil_a == 'aaa'">
        <select v-model="pil_olga" name="ooo" id="ooo">
         <option value="">-- Pilih OOO --</option>
         <option v-for="o in ooo" :value="o">{{o}}</option>
        </select>
       </div>
      </div>
      <?php /* {{-- End of pilihan --}} */ ?>
     </div>
     <div class="modal-footer">
      <span class="pull-left">Klik simpan</span>
      <button type="button" class="btn btn-default" data-dismiss="modal">Batal</button>
      <button id="save-pilihan" type="button" class="btn btn-primary">Simpan</button>
     </div>
    </div><!-- /.modal-content -->
   </div><!-- /.modal-dialog -->
  </div><!-- /.modal -->
 </div>

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
 <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
 <script src="https://unpkg.com/vue"></script>
 <script>
  $(document).ready(function(){
   $('#save-pilihan').on('click', function(event){
    $.ajax({
                    type : "POST",
                    url  : 'test2post.php',
                    data :  {
                        ordinal: 1,
                        bbb: $('#bbb').val(),
      jkjkjk: $('#jkjkjk').val(),
      ppp: $('#ppp').val(),
      jjj: $('#jjj').val(),
      kkk: $('#kkk').val(),
      ooo: $('#ooo').val()
                    },
                    dataType : 'json',
                    complete : function(data){
                     console.log(data.responseText);
                     if(data.responseText == '1'){
                      $('#myModal').modal('hide');
                     }
                    }
                });
   });
  });
  
  new Vue({
   el: '#app',
   data: {
    pilihan: [],
    jk: [],
    didi: [ "U" , "A"],
    kkk: [],
    ooo: [],
    pil_a: "",
    pil_jk: "",
    pil_d: "",
    pil_skill: "",
    pil_olga: ""
   },
   methods: {
    milih_jk: function (event) {
     console.log(this.pil_jk);
     if(this.pil_a == 'ugl'){
      if(this.pil_jk == 'a'){
       this.kkk = ["a","b"];
      }
      if(this.pil_jk == 'b'){
       this.kkk = ["MC"];
      }
     }
    }
   }
  })
 </script>
</body>
</html>

May 25, 2017

How to Run Laravel Application on a Shared Hosting

Few of my friends asked me how to upload and run a Laravel application on a shared, non-VPS, hosting. So I thought of writing the answer to their question in this article. If you happen to be asking the same question as my friends, welcome and follow along..

Note: this tutorial has been tested on a shared hosting with CPANEL. Feel free to ask me on the comment section if you have other than CPANEL shared hosting services and this tutorial doesn't work.

Ok, here we go..

Step 1. Login to your CPANEL


CPANEL Login Form

Make sure you entered the correct credentials. Most hosting companies will disable your account or block your IP address upon several consecutive login failure. The hosting company whom I subscribed to will block my IP address after my third failure login attempts.

If this actually happens, maybe because you forgot your password, just contact your hosting company. They will gladly help to solve your problem.

Step 2: Open the File Manager

After succesfully logged in to your CPANEL, you will find a lot of features displayed on your CPANEL dashboard. If you are new to CPANEL, don't be overwhelmed, just click on the File Manager button/icon.


Next, click on the "Add Folder" button. This button is located somewhere on the upper section of the file manager page.


When a "New Folder" menu pops out, type the word "core"inside the New Folder Name input box. Make sure that the second input box which says "New Folder will be created in" is empty. This will create the core folder on the root folder of your UNIX directory (you can confirm this by seeing that the core and public_html are located at the same folder)


Once the core directory has been created, we are ready to upload from local project to shared hosting via FTP.

Step 3: Upload Files

We are going to do the upload in two parts. The first part is to upload all of files and folder, except the public directory, into the core directory we have created in the previous step. Use an FTP client and connect to your hosting service's FTP server. I like to use FileZilla, since it's free and seazy to use.

Copy all but the public local direcotry to the remote core directory

Once we are done uploading to the core directory, we will continue to the second part. Open the public directory on your local machine, and open the public_html directory on your remote server. Now upload all files and folders inside the public local directory to the public_html remote directory.

Upload all files inside public to public_html

Remember, do not upload any files or folder outside the local public directory to public_html, because the public_html directory is accessible through the internet. If you accidentally upload, for example the .env file, then your database, SMTP, or any other crucial credentials might be exposed. Immediately change your credentials if this happens.

Also, according to the Laravel installation guide, you have to allow the storage and the bootsrap/cache directory to be writable and executable.

Step 4: Changing Permissions for storage and bootstrap/cache

To change permission for the the storage directory, do this:
  1. Open the core directory.
  2. Right-click on the storage directory
  3. Click on the File Permission that shows up on the pop-up menu. 
  4. Type in the lucky seven number (777) on the "Numeric Value" input box. 
  5. Make sure that the "Recurse into subdirectories" checkbox is checked.
  6. Select the "Apply to all files and directories" radio button
  7. Click the OK button,
Right-clik storage, and click File Permissions

Give all Read-Write-Execute permission recursively

To change permission for the the bootstrap/cache directory, do this:
  1. Open the core directory, then get inside the bootstrap directory.
  2. Right-click on the cache directory
  3. Click on the File Attributes that shows up on the pop-up menu. 
  4. Type in the lucky seven number (777) on the "Numeric Value" input box. 
  5. Make sure that the "Recurse into subdirectories" checkbox is checked.
  6. Select the "Apply to all files and directories" radio button
  7. Click the OK button,
Right-click bootstrap/cache, and select File Attributes

Give all Read-Write-Execute permission recursively

Great, all file permissions has been given. Now it's time to tweak the index.php file.

Step 5: Edit the index.php File

Since we separate the application into two directories, core and public_html, we need to tell Laravel that some directories are no longer in their default location. The way we tell this fact to Laravel is to open the index.php file located inside the public_html directory.

From the CPANEL file manager, click the public_html directory on the left directory tree panel. Then on the file lists on the right, click on the index.php file.


Next click the Edit button somewhere on the upper menu.


Next, find this line:
require __DIR__.'/../bootstrap/autoload.php';
and change it to become like this
require __DIR__.'/../core/bootstrap/autoload.php';
Similarly, do the same for this line:
$app = require_once __DIR__.'/../bootstrap/app.php';
and change it to become like this
$app = require_once __DIR__.'/../core/bootstrap/app.php';

Final Step: Open Your App in a Browser

The last step is to simply open your favorite web browser, and type in your application's URL. Go then, give it a try..!

April 22, 2017

Beautifying Tables when Exporting PDF with Laravel

In many occation, my clients wanted their data to be exported into a PDF file so that it is portable and ready to print whenever the needed to. There are times when we, as a developer, need to generate those data in form of tables. The tricky part is to make tables look nice in a PDF file when exporting data with the help of PHP. In this article I am going to share some experience to make your tables look nice on a export-to-pdf process.

 Suppose that a client has an employees table that he wants to export into a PDF file with table-formatted like this:
Employees table

Step 1 : Add an "Export to PDF" Button

The first thing that we should do, of course, is to add an "Export to PDF" button somewhere on the page. In this case, I put it below the pagination buttons. Open the view file and add these html lines:

<div class="text-center">
    <a href="{{ url('/employees/export-to-pdf') }}" class="btn btn-primary">
        Export to PDF
    </a>
</div>

Notice that the href attribute of the anchor tag (the button) is leading to /employees/export-to-pdf. So later we need to make a route for it. For now, let's just save the view file, and refresh the page in the browser. It should look like this:

An "Export to PDF" button has been added

Step 2 : Install a PDF Library

Next we need to install a tcpdf library that works well with laravel. I'm not recommending any specific package, but since use it in most of my projects, I will be using tcpdf-laravel from elibyy throughout this article.

Open the terminal, enter your laravel project directory, and run this artisan command:

composer require elibyy/tcpdf-laravel

After composer is done installing the package, open up the config/app.php file, and add this line somewhere inside the providers array

Elibyy\TCPDF\ServiceProvider::class,

Also, add this line somewhere inside the aliases array:

'PDF' => Elibyy\TCPDF\Facades\TCPDF::class,

Now save the file and open the routes/web.php file.

Step 3 : Add a Route

Add this line to make a route for our /employees/export-to-pdf url:

Route::get('/employees/export-to-pdf', 'EmployeeController@exportToPdf');
Note that if you don't have the controller, create it before you add the route. This is how you create a controller from the terminal:

php artisan make:controller EmployeeController

Now save the file, and get ready put some code in the controller.

Step 4 : Add a Method in The Controller

Next, open up the app/Http/Controllers/EmployeeController.php file, and add a public method as we defined previously in the route.

public function exportToPdf()
{
    $employees = \App\User::all();
    $html = view('employees-pdf', compact('employees'));

    PDF::SetTitle('Employees Table');
    PDF::SetPrintHeader(false);
    PDF::SetPrintFooter(false);
    PDF::SetMargins(20, 10, 15);
    PDF::AddPage('P','LEGAL');

    PDF::writeHTML($html, true, false, true, false, '');
    $filename = public_path() . '/files/employees.pdf';
    PDF::output($filename,'I');
}

Here is how it works:
  • The first two lines of the method, are to gather all of the employees data, and load it into a view file named resources/views/employees-pdf.blade.php. Then store the view to a variable $html.
  • The next five lines are the PDF settings.
  • The last three lines are to save the view to a pdf file named /files/employees.pdf, relative to the public directory (also relative to the domain name of the application).
  • Note that on the last line, the second parameter 'I' is to directly stream the pdf to the browser. So you will be able to instantly see the PDF as a response of the /employee/esport-to-pdf url.

Step 5 : Create a View File

According to the exportToPdf method on the EmployeeController, There is supposed to be a view file named resource/views/employees-pdf.blade.php. so create the file if it hasn't been created yet. Open the file and put these html code:

<!DOCTYPE html>
<html>
<head>
    <title>Employees</title>
</head>
<body>
        <h1>Employees Table</h1>
        <table class="table table-bordered" cellpadding="5" width:"100%">
            <tr>
                <th><div>ID</div></th>
                <th><div>Name</div></th>
                <th><div>Age</div></th>
                <th><div>Division</div></th>
                <th><div>Salary</div></th>
                <th><div>Performance</div></th>
            </tr>
            @foreach($employees as $employee)
            <tr nobr="true">
                <td>{{ $employee->id }}</td>
                <td>{{ $employee->name }}</td>
                <td>{{ $employee->age }}</td>
                <td>{{ $employee->division }}</td>
                <td>{{ $employee->salary }}</td>
                <td>{{ $employee->performance }}</td>
            </tr>
            @endforeach
        </table>
</body>
</html>

Save it and test the "Export to PDF" button from the browser. It should look something like this:

Messy Employees Table

Okay it works.. But.. It is sooo ugly..
We need to tweak the HTML mockup to beautify the table. Back to the employees-pdf.blade.php file.

Add some styling just above the closing </head> tag

...
<style>
    .text-center{text-align:center;}
    .text-right{text-align:right;}
    td,th{border:1px solid #000000;}
</style>
...

Add a pair of <thead></thead> tag after the first closing </tr> tag, and fill it with these:

...
<thead>
    <tr>
        <th width="50"><div class="text-center">1</div></th>
        <th width="200"><div class="text-center">2</div></th>
        <th width="50"><div class="text-center">3</div></th>
        <th><div class="text-center">4</div></th>
        <th width="70"><div class="text-center">5</div></th>
        <th><div class="text-center">6</div></th>
    </tr>
</thead>
...

The thead pairs will allow anything it contained to be displayed on each and every page.

Next, add an opening <tbody> tag before the @foreach statement, and also a closing </tbody> tag after the @endforeach statement.

...
<tbody>
    @foreach($employees as $employee)
        <tr>
            ...
        </tr>
    @endforeach
</tbody>
...

Next, adjust the width of the column titles, by following the width we defined in thead above

...
<tr>
    <th width="50">ID</th>
    <th width="200">Name</th>
    <th width="50">Age</th>
    <th>Division</th>
    <th width="70">Salary</th>
    <th>Performance</th>
</tr>
...

Lastly, center some columns by applying a corresponding class that we defined in the style tag above. Overall, the final version of the employees-pdf.blade.php file will be like this:

<!DOCTYPE html>
<html>
<head>
    <title>Employees</title>
    <style>
        .text-center{text-align:center;}
        .text-right{text-align:right;}
        td,th{border:1px solid #000000;}
    </style>
</head>
<body>
        <h1>Employees Table</h1>
        <table class="table table-bordered" cellpadding="5" width:"100%">
                <tr>
                    <th width="50"><div class="text-center">ID</div></th>
                    <th width="200"><div class="text-center">Name</div></th>
                    <th width="50"><div class="text-center">Age</div></th>
                    <th><div class="text-center">Division</div></th>
                    <th width="70"><div class="text-center">Salary</div></th>
                    <th><div class="text-center">Performance</div></th>
                </tr>
            <thead>
                <tr>
                    <th width="50"><div class="text-center">1</div></th>
                    <th width="200"><div class="text-center">2</div></th>
                    <th width="50"><div class="text-center">3</div></th>
                    <th><div class="text-center">4</div></th>
                    <th width="70"><div class="text-center">5</div></th>
                    <th><div class="text-center">6</div></th>
                </tr>
            </thead>
            <tbody>
                @foreach($employees as $employee)
                <tr>
                    <td><div class="text-center">{{ $employee->id }}</div></td>
                    <td>{{ $employee->name }}</td>
                    <td><div class="text-center">{{ $employee->age }}</div></td>
                    <td>{{ $employee->division }}</td>
                    <td>
                        <div class="text-right">
                            $ {{ number_format($employee->salary,0,',','.') }}
                        </div>
                    </td>
                    <td>
                        <div class="text-center">
                            {{ $employee->performance }}
                        </div>
                    </td>
                </tr>
                @endforeach
            </tbody>
        </table>
</body>
</html>

Save the file and test it out in the browser. It will look something like this:

Good Looking Table

Better.. But hey, if you look at the bottom at each page, there will be an ugly breaking.

Static Column Title, But Ugly Breaks

Well.. That is eazy.. Just add a nobr="true" attribute on the tr tag under the @foreach statement line

...
<tbody>
    @foreach($employees as $employee)
        <tr nobr="true">
            ...
        </tr>
    @endforeach
</tbody>
...

Save the file again, and test it in the browser. It will look something like this:

Nice Break

Amazing.. We just got ourselves a nice and neat table. Why don't you give it a try and leave a comment below.

Happy coding ^_^

April 18, 2017

Mass-generating QR-Code Coupon with Laravel

Okay, so my client asked me to generate some discount coupons for his loyal customers on hteir next visit to his cafe. The coupons must each have unique QR-code, so that the cashier lady could scan it and automatically reducing the total amount that the customer must pay.

That's eazy.. But..

He asked me to generate 1000 coupon codes! It would pretty sure took days to accomplish using photoshop *_*

Sleek-looking Discount Coupon

So I decided to mass-generat it using laravel. And with some "plugin" packages, of course. Here is how I did it.

Step 1 : Prepare a template for the discount coupon

The template could just be a JPEG or a PNG image file.

A coupon template I got from my client

Copy this file into the storage/app/ directory. Rename it to template.png, or template.jpg depending on original file type.

Step 2 : Install a QR Code Package

Assuming you already have a Laravel application running, get a qrcode package. I used milon/barcode by the way. Run this command on the terminal:

composer require milon/barcode

And wait until the package installation completed successfully. After the installing the qrcode, open up the config/app.php file and add this line Milon\Barcode\BarcodeServiceProvider::class somewhere in the providers array, and also add these two lines 'DNS1D' => Milon\Barcode\Facades\DNS1DFacade::class and 'DNS2D' => Milon\Barcode\Facades\DNS2DFacade::class somewhere inside the aliases array. I would look like this, afterward:

'providers' => [
    ...
    Milon\Barcode\BarcodeServiceProvider::class,
    ...
]
...
'aliases' => [
    ...
    'DNS1D' => Milon\Barcode\Facades\DNS1DFacade::class,
    'DNS2D' => Milon\Barcode\Facades\DNS2DFacade::class,
]

Step 3 : Create the Artisan Command for Generating Coupons

Take the advantage of Laravel's artisan command to mass-generate 1000 discount coupons. But first let's create a command that will do that. Run this command from the terminal:

php artisan make:command GenerateCoupons

This command will create a new file called GenerateCoupons.php inside the app/Console/Command/ directory. Open the file and pour some code into it.

Find a line that looks like this:
protected $signature = 'email:send {user}';
and change it into this
protected $signature = 'generate:coupon {how_many}';

Basicly, what this line provides is that, I will be able to run "generate:coupon" command from the terminal with an argument defining how many discount coupons we want to generate. For example, if I want to generate 1000 discount coupons, I would simply run "generate:coupon 1000" from my terminal.

Awesome...

Next, time to put some real coding here. Find the handle() function and add some serious codes ^_^ :

public function handle()
{
    $count  = $this->argument('how many');
    $img    = \Image::make(storage_path().'/app/template.png');
    for($i=1;$i<=$count;$i++) {
        $qrcode = \Image::make( base64_decode(\DNS2D::getBarcodePNG($base_url.$code, "QRCODE")))->heighten(390);
        $img->insert($qrcode, 'top-left',372,79);
        $img->save(public_path('qr/').$code.'.png',130);
        $this->info($i.' generated');
    }
}
If you have different template file from the one that I have, you can adjust the size of your qr-code, and also adjust the qr-code positioning relative to the template. Just change the number inside the heighten() function to adjust qr-code size (in pixels). Change the second, third, and fourth parameter of the insert() function to adjust the relative position of the qr-code relative to the template. Note that the second parameter could be any of these values:
  • top-left
  • top-right
  • bottom-left
  • bottom-right
This is the illustration how I measured those parameters:
Save this file and, open the next one, app/Console/Kernel.php.

Step 4 : Registering the Command

So we are currently editing the Kernel.php file. Find this line
protected $commands = [
    Commands\SendEmails::class
];
And change it to
protected $commands = [
    Commands\GenerateCoupons::class
];
this will register our GenerateCoupons class so that Laravel's artisan can recognize and able to execute it via the command name.

Step 5 : Moment of Truth

Run this from the terminal:

php artisan generate:coupon 1000

To find out whether the command successfully generating 1000 discount coupons, open up the public/coupons/ folder.

How's that? Pretty cool huh? Why don't you give it a try and leave a comment below

March 12, 2017

10 Easy Step to Setup Laravel Passport as Your API Authentication

Recently I'm working on a project where my role is to provide the back-end API required by a front-end application to access some content. And because recently Laravel comes with Passport (since version 5.3), I thought I could leverage and implement it on this project.

At first, I was only relying on the documentation and also laracasts video to setup Passport. But as I go through, some undocumented steps are missing that I had to google it. Luckily I found a a solution from stackoverflow, and my project is back on schedule. Perhaps some of you experiencing the same problem, as I did, here are 10 easy direct steps you can follow (copy & paste) along without any hassles.

Ready?
Here we go...

  1. Run composer require laravel/passport from your shell (command prompt on Windows).
  2. Open the config/app.php file, and add Laravel\Passport\PassportServiceProvider::class somewhere inside the $providers array
  3. Run php artisan:migrate from your shell.
  4. Still at your shell, run php artisan passport:install.
  5. Open the User model class, it is located at app/User.php, and add use Laravel\Passport\HasApiTokens; somewhere between the namespace and the class declaration, also use this HasApiTokens trait inside the class like so use HasApiTokens, Notifiable;.
  6. Open the app/Providers/AuthServiceProvider.php file, and add use Laravel\Passport\Passport;
    between the namespace and the class declaration, and also add this line Passport::routes(); inside the boot() function.
  7. Open the config/auth.php file and change the API driver from token to passport
  8. If you intend to consume your API from the same Laravel application, simply open the app/Http/Kernel.php file, and add \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class inside the $web array.
  9. Run php artisan passport:client to create an Oauth2 client for your API. From this step, you will get a personal access token.
  10. Use the personal access token you get from step #9 and use it to hit your API.
Note that you request header should contain attributes in these formats (mind the space character before the token):
  •  Authorization : "Bearer <token>"
  • Accept : application/json
That's it. I hope this article can be of any use for anyone who is about to start their backend Laravel project with Passport. If you have any question or not sure of what I meant on any of the above steps, feel free to ask in the comment section below.

Happy coding guys ^_^