Tuesday 31 July 2018

Unit Test Auto Generate for Laravel

Creating unit test for all the routes will be very difficult if you have large number of routes and parameters.

This package will automatically generate the unit test file for all of your routes and based on the form request files, to use the package install the package using composer

composer require vigneshc91/laravel-test-generator

After installing run the artisan command to generate the files

php artisan laravel-test:generate

You can use the available options to generate test file in  specific directory, or for some specific route prefix by using the options in that package

Ref : https://vigneshc91.github.io/laravel-test-generator/

Tuesday 24 July 2018

Validation Auto Generate For Laravel

Creating validation file for all the tables will be very difficult if you have large number of tables and columns.

This package will automatically generate the validation request file for all of your tables in the database, to use the package install the package using composer

composer require vigneshc91/laravel-validation-generator

After installing run the artisan command to generate the files

php artisan laravel-validation:generate

You can use the available options to generate rules for specific tables, or ignore specific tables or columns by using the options in that package

Ref : https://vigneshc91.github.io/laravel-validation-generator/

Wednesday 18 July 2018

Swagger Auto Generate For Laravel

Manually writting the swagger is always a tedious process either you write the json file or writing the swagger annotation to generate the json file

This package will automatically generate the swagger files by scanning the form request files, The package can easily be installed by running the composer in your project’s root folder.

    composer require vigneshc91/laravel-swagger

After installation to generate the swagger run the command in your terminal

    php artisan laravel-swagger:generate --filter="api" --auth="jwt" > public/docs/swagger.json

You can use several options available in that Ref: https://vigneshc91.github.io/laravel-swagger/

Tuesday 3 July 2018

Log Viewer For Laravel Projects

Viewing of log files in the laravel is always a tedious part if you run into some issues and opening the log file from the stroage folder and find for the appropriate error message

If you are experiencing that kind of problems here is a package available for that, which has great UI and easy to find log

Log Channel - Stack

  • Add rap2hpoutre/laravel-log-viewer into your composer.json file or run composer require rap2hpoutre/laravel-log-viewer
  • Add Route::get('logs', '\Rap2hpoutre\LaravelLogViewer\LogViewerController@index');  into your route file
  • Go to http://{your-project}/logs to see your logs
  • This works also for daily log channel
  • Ref : https://github.com/rap2hpoutre/laravel-log-viewer
composer require rap2hpoutre/laravel-log-viewer

Log Channel - Daily

  • If your are using daily log channel you can use another package which has more features than the previous one
  • Add arcanedev/log-viewer into your composer.json file or run composer require arcanedev/log-viewer
  • Go to http://{your-project}/log-viewer to see your logs
  • Ref : https://github.com/ARCANEDEV/LogViewer
composer require arcanedev/log-viewer

Tuesday 28 November 2017

On Demand Image Resizing With AWS

Delivering the image according to the device and resolution is always a big challenge. If you want to convert the image dynamically based on the resolution without using any expensive service provider like cloudinary, here is the solution for you which uses the Amazon resources.

AWS offers a simple solution that automatically deploys and configures a serverless architecture that is optimized for dynamic image manipulation. The diagram below presents the Serverless Image Handler architecture you can deploy in minutes using the solution's implementation guide and accompanying AWS CloudFormation template.


  • Amazon CloudFront provides a caching layer to reduce the cost of image processing.
  • Amazon API Gateway provides API endpoint powered by AWS Lambda functions to dynamically make image modifications.
  • AWS Lambda retrieves the image from the existing Amazon Simple Storage Service (Amazon S3) bucket and uses Thumbor to return a modified version of the image to the API Gateway.
  • The API Gateway returns the new image to CloudFront for delivery to end-users.

To implement this solution simply click on this link

The On demand image manipulation is done by the Thumbor service and it offers lots of filters, to see full list of available options click on this link

Finally you can resize the image with the url like http://cloudfront…/500x500/path/image01.jpg

You can apply filters like http://cloudfront…/filters:blur(80)/path/image01.jpg

You can combine both the resize and filters.

Refference: http://docs.aws.amazon.com/solutions/latest/serverless-image-handler/deployment.html

Thursday 2 March 2017

Bundling Angular 2 systemjs application for production

To deploy the angular 2 application for production, we must bundle it to make the application to run faster. Here are the steps for bundling the application using systemjs builder and gulp task

Include the following in the devDependencies of package.json file
"devDependencies":{
    ...
    "gulp": "^3.9.1",
    "gulp-clean": "^0.3.2",
    "gulp-html-replace": "^1.6.1",
    "gulp-shell": "^0.5.2",
    "lite-server": "^2.2.2",
    "run-sequence": "^1.2.2",
    "systemjs-builder": "^0.15.31",
}
Create vendor.ts file inside the app folder with the following contents
import 'core-js-shim';
import 'zone';
import 'reflect';
Include these libraries in the map section of systemjs.config.js to bundle it
 map: {
    ...
    'text': 'plugin-text.js',
    
    //shims
    'core-js-shim':'npm:core-js/client/shim.min.js',
    'zone':'npm:zone.js/dist/zone.js',
    'reflect':'npm:reflect-metadata/Reflect.js'
}
Create plugin-text.js with the following contents to bundle the html files
exports.translate = function(load) {
    if (this.builder && this.transpiler) {
        load.metadata.format = 'esm';
        return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';';
    }

    load.metadata.format = 'amd';
    return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});';
}

Create a gulpfile.js file with the following contents to bundle the dependencies
var gulp = require('gulp');
var shell = require('gulp-shell');
var clean = require('gulp-clean');
var htmlreplace = require('gulp-html-replace');
var runSequence = require('run-sequence');
var Builder = require('systemjs-builder');
var builder = new Builder('', 'systemjs.config.js');

var bundleHash = new Date().getTime();
var mainBundleName = bundleHash + '.main.bundle.js';
var vendorBundleName = bundleHash + '.vendor.bundle.js';

// This is main task for production use
gulp.task('dist', function(done) {
    runSequence('clean', 'compile_ts', 'bundle', function() {
        done();
    });
});

gulp.task('bundle', ['bundle:vendor', 'bundle:app'], function () {
    return gulp.src('index.html')
        .pipe(htmlreplace({
            'app': mainBundleName,
            'vendor': vendorBundleName
        }))
        .pipe(gulp.dest('./dist'));
});

gulp.task('bundle:vendor', function () {
    return builder
        .buildStatic('app/vendor.js', './dist/' + vendorBundleName)
        .catch(function (err) {
            console.log('Vendor bundle error');
            console.log(err);
        });
});

gulp.task('bundle:app', function () {
    return builder
        .buildStatic('app/main.js', './dist/' + mainBundleName)
        .catch(function (err) {
            console.log('App bundle error');
            console.log(err);
        });
});

gulp.task('compile_ts', ['clean:ts'], shell.task([
    'tsc'
]));

gulp.task('clean', ['clean:ts', 'clean:dist']);

gulp.task('clean:dist', function () {
    return gulp.src(['./dist'], {read: false})
        .pipe(clean());
});

gulp.task('clean:ts', function () {
    return gulp.src(['./app/**/*.js', './app/**/*.js.map'], {read: false})
        .pipe(clean());
});
Finally include the generated js in the index.html file, the index.html may look like
<!DOCTYPE html>
<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <my-app>Loading...</my-app>
    <script src="dist/1474222768447.vendor.bundle.js"></script>
    <script src="dist/1474222768447.main.bundle.js"></script>
  </body>
</html>

Friday 20 January 2017

Datepicker In Angular 2

To use the datepicker in the angular 2 application use ng2-bootstrap
include ng2-bootstrap and moment in your package.json and hit npm install to install both in the node_modules
include datepicker module in your module file. The app.module.ts file will be,
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DatepickerModule } from 'ng2-bootstrap/ng2-bootstrap';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { DatepickerComponent } from './datepicker.component';

@NgModule({
  imports:      [ BrowserModule, DatepickerModule],
  declarations: [ AppComponent, DatepickerComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }
    
Create the text box in html and write the functionality in the ts file like
<div class="container">
    <div class="col-md-6">
        <label for="datepicker" class="text-primary">Date Picker</label>
        <div class="input-group date-picker">
            <input type="text" class="form-control" name="datpicker" id="datpicker" placeholder="Date Picker" [(ngModel)]="datePickerValue" (focus)="showDatePicker()" readonly>
            <span class="input-group-addon" (focus)="showDatePicker()"><span class="glyphicon glyphicon-calendar" aria-hidden="true"></span></span>
        </div>
        <div class="dp-popup" *ngIf="isDatePickerShown">
            <datepicker [(ngModel)]="datePickerDate" [showWeeks]="false" [maxDate]="today" [ngModelOptions]="{standalone: true}" (selectionDone)="dateSelected($event)"></datepicker>
        </div>   
    </div>
</div>
    
import { Component, OnInit, ViewChild } from '@angular/core';
import { DatepickerModule } from 'ng2-bootstrap/ng2-bootstrap';
import * as moment from 'moment';

@Component({
    selector: 'datepicker-component',
    templateUrl: 'datepicker.component.html',
    host: {
        '(document:click)': 'handleClick($event)'
    },
})

export class DatepickerComponent {
    
    isDatePickerShown:boolean = false;
    datePickerDate;
    datePickerValue;
    today:Date = new Date();

    constructor() {
        
    }

    showDatePicker(){
         this.isDatePickerShown = true;
     }

     hideDatePicker(){
         this.isDatePickerShown = false;
     }

     dateSelected(event){
         this.datePickerValue = moment(event).format("YYYY-MM-DD");
         this.hideDatePicker();
     }

     handleClick(event){
         if(!(event.target.closest('datepicker') != null || event.target.closest('.btn') != null || event.target.closest('.date-picke') != null)){
             this.hideDatePicker();
         }
     }

}