Showing posts with label Laravel. Show all posts
Showing posts with label Laravel. Show all posts

Tuesday, 26 March 2019

Resolve an issue to insert explicit value for identity column in SQL table asking for IDENTITY_INSERT to set ON/OFF in PHP (Laravel)

The following methods to control the `IDENTITY_INSERT` to ON/OFF for SQL table seeding process in PHP (Laravel) :
    
    function setIdentityInsert($table, $onStatus = true)
    {
        $status = $onStatus ? 'ON' : 'OFF';

        $this->sqlConnection->unprepared("SET IDENTITY_INSERT $table $status");
    }

    function insertTableData($table, $data)
    {
        return $this->sqlConnection->table($table)->insert($data);
    }

    function seedTable($table, $hasAutoIncrementPrimaryKey = false, $data = [])
    {
        if ($hasAutoIncrementPrimaryKey) {
            $this->setIdentityInsert($table);
            $response = $this->insertTableData($table, $data);
            $this->setIdentityInsert($table, false);

            return $response;
        }
        else {
            return $this->insertTableData($table, $data);
        }
    }

Note: Generally, the table requires to have an auto-increment primary key to set Identity Insert to `ON`, that's why I have the `$hasAutoIncrementPrimaryKey` flag. Otherwise, seeding may throw an error as:
    
    SQLSTATE[HY000]: General error: 544 Cannot insert explicit value for
    identity column in table 'test_table_name' when IDENTITY_INSERT is set to
    OFF. [544] (severity 16) [(null)]
Hope this helps!

Thursday, 21 February 2019

Laravel - PHPUnit - run single test class or method

The following command runs the test on a single method: (e.g. we are testing the `testCreateUser()` method here)
vendor/bin/phpunit --filter testCreateUser UserControllerTest tests/feature/UserControllerTest.php
vendor/bin/phpunit --filter methodName ClassName path/to/file.php
Further, lets say you want to test a ClassName which exists into two location:
tests/unit/UserControllerTest.php // contains 3 tests
tests/feature/UserControllerTest.php // contains 2 tests
In this case, you simply run below command which will check for all the test on both location.
vendor/bin/phpunit --filter UserControllerTest

-----Output---------
Time: 2.56 seconds, Memory: 30.00MB

OK (5 tests, 22 assertions)
Please note, if you have phpunit available globally on your machine, you can simply run
phpunit --filter 

# instead of 
vendor/bin/phpunit --filter
Stackflow resource.

Thursday, 31 January 2019

Rename all existing files on AWS S3 Bucket using Laravel Storage library

Follow below steps to rename existing files on a selected directory on S3 Bucket.

1. Lets say your config/filesystems.php looks like this:
'disks' => [
  's3_test_bucket' => [
        'driver' => 's3',
        'key'    => env('AWS_KEY', 'your_aws_key_here'),
        'secret' => env('AWS_SECRET','your_aws_secret_here'),
        'region' =>  env('AWS_REGION', 'your_aws_region_here'),
        'version' => 'latest',
        'bucket'  => 'my-test-bucket',
  ],
];

2. Let's say, you have my-test-bucket on your AWS S3.

3. Lets say you have following files inside the my-test-bucket/test-directory directory.
i.e.
- test-files-1.csv
- test-files-2.csv
- test-files-3.csv

3. Call below function to rename existing files on a selected directory on S3 Bucket.
$directoryPath = 'test-directory';
$storage = new MyStorageRepository();
$storage->renameAnyExistingFilesOnImportDirectory('my-test-bucket', 'test-directory');

4. Output: files should be rename as below on my-test-bucket/test-directory directory:
- test-files-1--1548870936.csv
- test-files-2--1548870936.csv
- test-files-3--1548870936.csv

5. Include the below library class or methods on your class and you should be good.

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Storage;

class MyStorageRepository
{
    public function renameAnyExistingFilesOnImportDirectory($bucket, $directoryPath)
    {
        $directoryPath = App::environment() . '/' . $directoryPath;
        $storage = Storage::disk('s3_test_bucket');

        $suffix = '--' . time(); // File suffix to rename.

        if ($storage->exists($directoryPath)) {
            $this->renameStorageDirectoryFiles($directoryPath, $storage, $suffix);
        }
    }

    private function getNewFilename($filename, $suffix = null)
    {
        $file = (object) pathinfo($filename);

        if (!$suffix) {
            $suffix = '--' . time();
        }

        return $file->dirname . '/' . $file->filename . $suffix . '.' . $file->extension;
    }

    private function renameStorageDirectoryFiles($directoryPath, $storage = null, $suffix = null, $filesystemDriver = null)
    {
        if (!$storage) {
            $storage = Storage::disk($filesystemDriver);
        }

        // List all the existing files from the directory
        $files = $storage->files($directoryPath);

        if (count($files) < 1 ) return false;

        foreach($files as $file) {
            // Get new filename
            $newFilename = Helpers::getNewFilename($file, $suffix);

            // Renamed the files
            $storage->move($file, $newFilename);
        }
    }
}
  
Also, copy of ref here

Thursday, 24 January 2019

Laravel Method to check if the given record id exists on DB table or not.

public function isModelRecordExist($model, $recordId)
{
    if (!$recordId) return false;

    $count = $model->where(['id' => $recordId])->count();

    return $count ? true : false;
}

// To Test
$recordId = 5;
$status = $this->isModelRecordExist( (new MyTestModel()), $recordId);

// Outcome: true | false

Hope it helps!

Tuesday, 13 November 2018

SAML Auth login issue on local - undefined logger()

(1/1) FatalThrowableError
Call to undefined function App\Http\Controllers\logger()

in SamlController.php line 85
at SamlController->acs()
at call_user_func_array(array(object(SamlController), 'acs'), array())
in BoundMethod.php line 29


Enable the Saml debugger by adding the `SAML2_DEBUG=true` on .env.

Then, found the following error:
openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate!
Whoops, looks like something went wrong.
(1/1) FatalThrowableError
Call to undefined function App\Http\Controllers\logger()

in SamlController.php line 87
at SamlController->acs()
at call_user_func_array(array(object(SamlController), 'acs'), array())
in BoundMethod.php line 29
at BoundMethod::Illuminate\Container\{closure}()
in BoundMethod.php line 87


Resolved the issue after updating with the correct `SAML2_IDP_X509CERT` value.

Thursday, 19 October 2017

To create a custom token password reset in Laravel 5.5 (Or Lumen)

Please use the below passwordResetToken() function to get the token for password reset for custom use.

namespace App\Traits;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Password;

trait ResetPasswordTrait 
{
    ...
    ...
    ...
    ...

    /**
     * Get the token for password reset and update the token in the database table.
     *
     * @return string|null
     */
    public function passwordResetToken($user)
    {
        $this->broker = 'users';

        $broker = $this->getBroker();

        return Password::broker($broker)->createToken($user);
    }

    /**
     * Get the broker to be used during password reset.
     *
     * @return string|null
     */
    public function getBroker()
    {
        return property_exists($this, 'broker') ? $this->broker : null;
    }

}


// Reuse in the class
use App\Traits\ResetPasswordTrait;

class NewUserAccount 
{

    use ResetPasswordTrait;

    // Sample function to print the password reset token
    public function printPasswordResetToken(Request $request)
    {
        $user = User::find( $request->input('id') );
        $passwordResetToken = $this->passwordResetToken($user);
        print_r($passwordResetToken);
    }

}

Wednesday, 5 April 2017

Generating the Laravel/Lumen Migrations from ER Diagram Model using MySQLWorkbench

To install the Migration Exporter from MySQL Workbench

Install thehttps://github.com/beckenrode/mysql-workbench-export-laravel-5-migrations/blob/master/export-laravel-5-migrations.py from Workbench > Scripting > Install Plugin/Module and browse the `export-laravel-5-migrations.py` file.

Then, go to Workbench > Tools > Catalog > Export Laravel 5 Migration and click on "Save the Migrations to the Folder..."

However got the following error: (Workbench > Help > Show Log File)
Error during "Export Laravel 5 Migration" 
Then, review the relationship index and foreign keys relations and amended few foreign keys which are not properly selected the reference columns.

Afterwards, tried generating the migration using above method, ultimately able to generate the migration.
However, found missing foreign keys relationship generated migration files.

To generate Laravel Migrations from MySQL Workbench:

To build the migrations with foreign constrains using following steps:
  1. Export the model using MySQL Workbench > File > Export > Forward Engineer approach as sample_database.sql file
  2. Create the database called 'sample_database'.
  3. Next, Import the sample_database.sql file into the above created database to build tables, which will populate all tables from the script. (you can also directly execute all the scripts from that .sql file instead, from the Query Builder)
    Note: Please make sure all the foreign keys relationships are created along with tables, once you find all the relationship are in place.
  4. Then, go to the MySQL Workbench > Database > Reverse Engineer, and establish the connection and select the database to regenerate the Model (ERD).
    This allows the MySQL Workbench to propagate the Tables' objects correctly which supports to generate the migrations.
  5. Lastly, go to Workbench > Tools > Catalog > Export Laravel 5 Migration and click on "Save the Migrations to the Folder..."
    If you already haven't install the Laravel 5 Migration plugin, refer above.

Tuesday, 4 April 2017

Configure Entrust on Laravel-lumen

## Configure Entrust on Laravel-lumen * In order to install Laravel 5 Entrust, just add the following to your composer.json. Then run composer update:
    "zizaco/entrust": "5.2.x-dev"
    
* Open your `bootstrap/app.php` and add the following to the providers array:
    $app->register(Zizaco\Entrust\EntrustServiceProvider::class);
    
* Create new `config/` directory on the project root folder. * Then, add the following package on `composer.json`:
    "laravelista/lumen-vendor-publish": "^2.0"
    
then, run
    composer update
    
* Create the `app/helpers.php` file and add the below function inside it.
    if (! function_exists('config_path')) {
        /**
         * Get the configuration path.
         *
         * @param  string  $patha
         * @return string
         */
        function config_path($path = '')
        {
            return app()->basePath() . DIRECTORY_SEPARATOR . 'config'.($path ? DIRECTORY_SEPARATOR.$path : $path);
        }
    }
    
* Add the following code into the `composer.json` inside the `autoload` after the `psr-4`
    "autoload": {
        "files": [
            "app/helpers.php"
        ]
    }
    
* Comment out the following line on `vendor/zizaco/entrust/src/Entrust/EntrustServiceProvider.php`
    //$this->bladeDirectives();
    
And, run the dump autolaod command:
    composer dump-autoload -o
    
* Then run the vendor publish command:
    php artisan vendor:publish
    

Monday, 20 March 2017

Resolve the issue with laravel session permission denied issue on Mac

Please follow the steps below.

1. Go to your project root folder via Finder where you keep all your projects and right click on it.


2. Then, click on "Get Info" and you will see the pop-up window.


3. At bottom-right of the window, there is 'Lock' icon, click on it to Unlock it.


4. Next, select the 'Read and Write' (if it was readonly) privilege for 'staff' name.


5. Afterwards, keep select the 'staff' name, then click to 'Setting' icon next to +/- signs, and select 'Apply to enclosed items...'.


6. Finally, click the 'Lock' icon to make it locked once you completed above steps


Then, your project file has full permission for Read/write and you don't need to `chmod 777` all time.





Username validation using Regis on Laravel

Please find the validation script below to fix the username validation allowing it to have only Alphanumeric with dot (.), dash/hypen (-) and underscore(_).

$validator = Validator::make($request->all(),
            ['user_name' =>
                ['required', 'min:4', 'max:20', 'unique:auth_users', 'Regex:/^[a-zA-Z0-9-._]+$/']
            ]


Monday, 6 June 2016

Resolving the issue with Gulp "Warning: gulp version mismatch:"

If you are getting the following types error:
[14:32:54] Warning: gulp version mismatch:
[14:32:54] Global gulp is 3.9.1
[14:32:54] Local gulp is 3.9.0
[14:32:56] Using gulpfile C:\xampp\htdocs\myproject\gulpfile.js
[14:32:56] Starting 'default'...
[14:32:56] Starting 'scripts'...
To resolve the issue,
First, go to your project root folder then run below two commands
npm update gulp -g 
npm update gulp

Thursday, 12 May 2016

List of Laravel Artisan Shortcuts (Alias) for Windows and MacOS

I would like to share the list of command alias I have created on my local to minimise the keystrokes with the Team.

Please go to the project root location via command line and just copy the below line (one line string) and run it:

alias cda="composer dump-autoload"; alias ci="composer install"; alias cu="composer update"; alias bi="bower install"; alias bu="bower update"; alias gi="gulp install"; alias ni="npm install"; alias pa="php artisan"; alias pam="php artisan migrate"; alias pamr="php artisan migrate:rollback"; alias pads="php artisan db:seed"; alias pades="php artisan db-exporter:seed"; alias pamm="php artisan make:migration"; alias pamc="php artisan make:controller"; alias pammd="php artisan make:model"; alias t="phpunit"; alias dat="php artisan app:droptables"; alias ga="git add"; alias gaa="git add ."; alias gc="git commit -m"; alias gp="git push"; alias gs="git status"; alias gl="git log"

The detail of the above string shortcut is below (if you want other way, feel free to change it with your comfort):

#Composer
alias cda="composer dump-autoload"
alias ci="composer install"
alias cu="composer update"

# Bower
alias bi="bower install"
alias bu="bower update"

# Gulp
alias gi="gulp install"
alias ggw="gulp && gulp watch"
# NPM alias ni="npm install" # Laravel alias pa="php artisan" alias pam="php artisan migrate" alias pamr="php artisan migrate:rollback" alias pads="php artisan db:seed" alias pades="php artisan db-exporter:seed" alias pamm="php artisan make:migration" alias pamc="php artisan make:controller" alias pammd="php artisan make:model" alias t="phpunit" # Laravel Custom alias dat="php artisan app:droptables" # Git alias ga="git add" alias gaa="git add ." alias gc="git commit -m" alias gp="git push" alias gs="git status" alias gl="git log"

Friday, 15 April 2016

AngularJS DataTable Plugin Rending the HTML with Angular Event Tigger such as ng-click

To make the Angular action trigger from the DataTable plugin, you just need add the below code within the loadDataTable Function.

// Define this function first.
function createdRow(row, data, dataIndex) 
{
 // Recompiling so we can bind Angular directive to the DT
 $compile(angular.element(row).contents())(scope);
}

// Then, add the below line with the "DTOptionsBuilder.newOptions()"
.withOption('createdRow', createdRow);

Please find the sample complete function with above added code.

Adding the AngurJS filter to Capitalize the first word, all words or all UPPERCASE

First, create the file 'capitalize.js' with the following contents.
/* capitalize.js file contents */

myapp.filter('capitalize', function() {
    return function(input, all) {
        var reg = (all) ? /([^\W_]+[^\s-]*) */g : /([^\W_]+[^\s-]*)/;
        return (!!input) ? input.replace(reg, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) : '';
    };
});

Then use the below example to adopt the code in your contexts;
To Capitalize the first word only
{{name | capitalize}} 
OUTPUT: "Hello world nepal"

To Capitalize the all words
{{name | capitalize:true}} 
OUTPUT: "Hello World Nepal"

The below example is for Data Table (angular-laravel library) rending html case:
/* In Data table rending html case */

var data = 'hello world nepal';
.renderWith(function (data, type, full) {
 return $filter('capitalize')(data)
})

// OUTPUT: "Hello world nepal"

.renderWith(function (data, type, full) {
 return $filter('capitalize')(data, true)
})
// OUTPUT: "Hello World Nepal"

/* and, For UPPERCASE */
.renderWith(function (data, type, full) {
 return data.toUpperCase();
})

// OUTPUT: "HELLO WORLD NEPAL"

Thursday, 31 March 2016

Get All First Letters or Abbreviation of Each Words of the sentence as a Abbreviated String using PHP

Please use the below function to pull all First Letters of Each Words of the sentence as a abbreviated String using PHP.

/**
 * Get the first letters or abbreviation of each words and as a uppercase string format.
 * @param $string Pass the parsing string
 * @return string String
 */
function getFirstLettersOfWords($string) {}
OR 
function getStringAbbreviation($string) 
{
 // Match the first letters of each words using regular expression.
 $matchFound= preg_match_all('/(\w)(\w+)/', $string, $matches);

 // Concatenate all the matched first letters as a string in upper case.
 $abbreviatedString= strtoupper( implode('', $matches[1]) );

 return $abbreviatedString;
}

Function Usage

$string1 = 'Distributor / Sub-Distributor';
$output1 = getStringAbbreviation($string1);

// Output: DSD

$string2 = 'Consultant (Registration, Licensing, Visa)';
$output2 = getStringAbbreviation($string2);

// Output: CRLV

Tuesday, 29 March 2016

Create the migrations for database views using php artisan in Laravel

Please follow the steps to create a sql views for Laravel using PHP Artisan using below step.

Step 1. Run below command:
php artisan make:migration create__views

Step 2. Open the migration file and add the below code:
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
     //
     DB::statement("
      CREATE VIEW views_overall_status AS
      (
       SELECT er.id AS auth_users_entity_roles_id, er.auth_users_id,
        e.checklists_id, c.overall_status_id AS status_id, s.name AS status_name
       
       FROM `auth_users_entity_roles` er
        LEFT JOIN entities e ON e.id=er.entities_id
        LEFT JOIN `checklists` c ON c.id=e.checklists_id
        LEFT JOIN `status` s ON s.id = c.overall_status_id
        
       WHERE s.slug = 'operating_risks' AND e.deleted_at IS NULL
        AND c.deleted_at IS NULL
      )
     ");
    }
    
    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down()
    {
     //
     DB::statement('DROP VIEW IF EXISTS views_overall_status');
    }

Step 3. To call and run the SQL Views via Laravel query
    $items = $DB::table('views_entities_by_overall_status')
                ->select('status_id', 'status_name', 'status_name_trans_text_id',
                    $DB::raw('count(entities_id) as counts')
                )
                ->groupBy('status_id')
                ->orderBy('counts' , 'desc')
                ->whereIn('entities_id', Auth::user()->getEntityRoleEntityIDs())
                ->get();
    print_r($items);

Hope that helps. Please let me know if anyone has better solution!!

Thursday, 10 March 2016

To Write a Sample Join Query in Laravel 5.2

Please follow the example below to write the the Multiple Join Query on Laravel 5.2
// NOTE: Please do not forgot add below line at the top to use DB instance
USE DB;
$whereClause = array( $this->table.".checklists_id" => 1 );
$items = DB::table($this->table)
->join('approval_states', 'approval_states.id', '=', $this->table.'.approval_state_id')
->join('approval_levels', 'approval_levels.id', '=', 'approval_level_conditions.approval_levels_id')
->select(
 $this->table.'.*',
 'approval_levels.name as level_name', 'approval_levels.level',
 'approval_states.state', 
 DB::raw("IF( approval_states.state='Approved','1','0' ) AS state_value")
)
->where($whereClause)
->where($this->table.'.deleted_at', null) // to ignore the soft deleted records.
->get();


Output Query (will produce the following JOIN query):
SELECT `approval_checklists`.*, `approval_levels`.`name` AS `level_name`, `approval_levels`.`level`, `approval_states`.`state`, 
IF( approval_states.state='Approved','1','0' ) AS state_value FROM `approval_checklists` 
INNER JOIN `approval_states` ON `approval_states`.`id` = `approval_checklists`.`approval_state_id` 
INNER JOIN `approval_levels` ON `approval_levels`.`id` = `approval_level_conditions`.`approval_levels_id` 
WHERE (`approval_levels`.`checklists_id` = 1) 
AND `approval_checklists`.`deleted_at` IS NULL

Hope it helps!!!

Writing the Subquery in Laravel 5.2

Please follow the example below to write the the Sub Query on Laravel 5.2:
// NOTE: Please do not forgot add below line at the top to use DB instance
USE DB;
$result = static::select('id')
->where( 'id', '!=', $currentLevelId)
->where('level', '>', DB::raw("(SELECT level FROM " . $this->table . " WHERE id='".$currentLevelId."')") )
->orderBy('level')->first();

Will produce the below subquery:
SELECT * FROM `approval_levels` WHERE `id` != 2 AND `level` > (SELECT LEVEL
FROM approval_levels WHERE id='2') ORDER BY `level` ASC LIMIT 1
Another Example:
$data = DB::table("items")
 ->select("items.*","items_count.price_group","items_count.quantity")
 ->join(DB::raw("(SELECT 
   items_count.id,
   GROUP_CONCAT(items_count.price) as price_group,
   FROM items_count
   GROUP BY items_count.id
   ) as items_count"),function($join){
  $join->on("items_count.id","=","items.id");
 })
 ->groupBy("items.id")
 ->get();

Hope it helps!

Thursday, 7 January 2016

To preview the executing or last Query Log in Controllers or Models in Laravel 5

To view/preview the executing query or last executed Query Log in Laravel 5 (including Laravel 4.2, Laravel 5.0, Laravel 5.2), please add the below code and run it.
 
// This is the Sample Controller
class SampleController extends Controller
{
 public function sampleControllerFunction()
 {
  $this->owner_id = 5;
  
  // Enable the Laravel Database Query Log
  DB::enableQueryLog(); 
  
  // Run your Query here
  $item = SampleModel::where('owner_id', $this->owner_id)->first();
  SampleModel::where('owner_id', $owner_id)->forceDelete();

  // Fetch and Print the Last Database Query Log
  print_r( DB::getQueryLog() ); 
 }
}

// This is the Sample Model
class SampleModel extends Model
{
 /**
     * The database table used by the model (mysql).
     *
     * @var string
     */
 protected $table = 'owner_list';

    /**
     * The attributes that are mass assignable..
     *
     * @var string
     */
    protected $fillable = ['id', 'owner_id'];
 
 public function getItemsList()
 {
  // Enable the Laravel Database Query Log
  DB::enableQueryLog(); 

  // Run your Query here
  $item = static::where('owner_id', $this->owner_id)->first();

  // Fetch and Print the Last Database Query Log
  print_r( DB::getQueryLog() ); 
 }
 
}


Please comment me if you have any queries


Monday, 4 January 2016

Adding Foreign Key on the Existing Table in Laravel 5.2 using php artisan command

To add a foreign key to the existing Table in Laravel 5.2 using php artisan command

Please run the below command:

  
// user_id: This is the name of your column on this format
// property_list: This is the name of reference table (e.g. to table, not from table)

$ php artisan make:migration add_foreign_key_for_user_id_column_to_property_list_table --table=property_list

Find below the sample class of the foreign key migration table
 
class AddForeignKeyForUserIdColumnToPropertyListTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('property_list', function (Blueprint $table) {
            //
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onUpdate('NO ACTION')->onDelete('NO ACTION');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('property_list', function (Blueprint $table) {
            //
            $table->dropForeign('property_list_user_id_foreign');
        });
    }
}