in Linux

Sort files by time modified

If you are editing multiple files on remote server and then you need to produce a release list, e.g. list of modified files, use this

find . -type f -printf '%T@ %P\n' | sort -n | awk '{print $2}'

You will get the latest files at the bottom of produced list.

Make Git ignore Mode changes

Sometimes I get tons of changes when doing git diff – even though I haven’t changed any of those files. This is then causing merges and issues when pulling new commits.

Solution that always works for me is to ignore change to file modes. E.g. permission changes.

git config core.fileMode false

Insightly CRM API can’t add a new TAG

If you are one of the unlucky ones in need of working with Insightly API, you have probably noticed there’s no way to create a TAG under Contact endpoint.

If you follow the documentation, you probably do a CURL request similar to this:


        $username = 'xxxxx'; // api key
        $ch = curl_init('https://api.insightly.com/v3.0/Contacts/');

        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Basic '. base64_encode($username)
        ]);

        $dataString = json_encode(array(
            'FIRST_NAME' => 'First',
            'LAST_NAME' => 'Last',
            'EMAIL_ADDRESS' => 'test@test.sk',
            "TAGS" => array(
                array("TAG_NAME" => "TEST")
            )
        ));

        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
        curl_setopt($ch , CURLOPT_HEADER, 1);
        curl_setopt($ch , CURLOPT_TIMEOUT, 30);
        curl_setopt($ch , CURLOPT_RETURNTRANSFER, TRUE);
        $return = curl_exec($ch );

        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($return, 0, $header_size);
        $body = substr($return, $header_size);

And all you get in return is 400 Bad Request!
Even if you try to update existing Contact using https://api.insightly.com/v3.0/Contacts/{ID}/Tags endoing you won’t have any more luck.

The solution is simple – go back to 2.3 endpoints – the exact same post data works on 2.3!

Insightly has done a really poor job on their API ..

Bottom line – change https://api.insightly.com/v3.0/Contacts/ to https://api.insight.ly/v2.3/Contacts/

Laravel Facebook Login guide how-to

This is a detailed guide how to implement Facebook login on your Laravel project.

If you are just starting, create new laravel project,

laravel new blog

Next you need to set up database, create .env file ( with credentials to your database ) and start by running following commands:

php artisan migrate
composer require laravel/socialite
composer require doctrine/dbal

Open config/app.php and add these 2 lines to appropriate sections:

'providers' => [
	Laravel\Socialite\SocialiteServiceProvider::class
],

'aliases' => [
	'Socialite' => Laravel\Socialite\Facades\Socialite::class
],

You can add these as the last items. Next open config/services.php and add in credentials from your facebook application. If you don’t have one yet, create it here https://developers.facebook.com/

'facebook' => [
        'client_id' => env('FACEBOOK_CLIENT_ID'),
        'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
        'redirect' => env('FACEBOOK_CALLBACK_URL')
]
And add these to your .env file. Example given:
FACEBOOK_CLIENT_ID=38268********
FACEBOOK_CLIENT_SECRET=6f8de45093*********
FACEBOOK_CALLBACK_URL=https://laravel.test/auth/facebook/callback

Next we need to make minor changes in database, so run:

php artisan make:migration facebook

and edit the newly created file in database/migrations/***_facebook.php Change it like this

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class Facebook extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table("users", function (Blueprint $table) {
            $table->string('facebook_id');
            $table->string('password', 255)->nullable(true)->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table("users", function (Blueprint $table) {
            $table->dropColumn('facebook_id');
        });
    }
}

– thrugh this we have added new column to users table called ‘facebook_id’ and more importantly, we have changed existing ‘password’ column to be nullable. Without this, it wouldn’t work.

You can execute these changes now

php artisan migrate

Almost there!
Edit app/User.php add facebook_id into list of editable fields, e.g.

protected $fillable = [
        'name', 'email', 'password', 'facebook_id'
];
And add a new function
public function addNew($input)
    {
        $check = static::where('facebook_id',$input['facebook_id'])->first();


        if(is_null($check)){
            return static::create($input);
        }


        return $check;
}
Which we will use in a moment. Next step update routes/web.php by adding following few lines
Route::get('facebook', function () {
    return view('facebook');
});
Route::get('auth/facebook', 'Auth\FacebookController@redirectToFacebook');
Route::get('auth/facebook/callback', 'Auth\FacebookController@handleFacebookCallback');
And last step ahead – create facebook controller.
php artisan make:controller Auth/FacebookController
change it to following
<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Http\Controllers\Controller;
use Socialite;
use Exception;
use Auth;

class FacebookController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function redirectToFacebook()
    {
        return Socialite::driver('facebook')->redirect();
    }
    
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function handleFacebookCallback()
    {
        try {
            $user = Socialite::driver('facebook')->user();
            $create['name'] = $user->getName();
            $create['email'] = $user->getEmail();
            $create['facebook_id'] = $user->getId();

            $userModel = new User;
            $createdUser = $userModel->addNew($create);
            Auth::loginUsingId($createdUser->id);

            return redirect('/u/');

        } catch (Exception $e) {
            return redirect('auth/facebook');
        }
    }
}

And that’s it! It’s done – you are a guru! Now just open any template where you want a login button and link to /auth/facebook page on your site. Upon successful authorization you will be redirected back to landing page, but you will be authorized now.

You can even update web.php to have your own “logged in only zone”, for example:


Route::get('/', 'PageController@welcome');
Route::get('login', 'PageController@login')->name('login');
Route::get('auth/facebook', 'Auth\FacebookController@redirectToFacebook');
Route::get('auth/facebook/callback', 'Auth\FacebookController@handleFacebookCallback');

Route::group(['middleware' => 'auth', 'prefix' => 'u'], function () {
    Route::get('/', 'LoggedInController@home');

});
And everything under /u/* url is for authorized users only.