3 of the best Javascript Searchable Select Boxes compared – Select2 vs Chosen vs Selectize.js performance

When having large amounts of jQuery/javascript select boxes that need to be searchable it is wise looking at the performance of them. I compared the following select replacement boxes: Select2, Chosen, Selectize.js, Bselect. Default Safari browser select box: initializing about 0.5s.

Setup

Having a backend page that has about 1000 select boxes that need to be initialized by a searchable/autocomplete selectbox. I checked the loading times of the page and the time of the initializitation of the select box. I measured it first by hand and later on by Safari web console.

Chosen performance

  • Measuring by hand: about 8s-11s.
  • Console measure: about 12s.Chosen select box performance

Cons:

  • Has no ajax support, if you want to do this, you can combine it with select2.

Select 2 performance

  • Measuring by hand: initializing takes about 9s-16s.
  • Console meaure:  about 21.69s.Select2 select box performance

Selectize.js performance

Selectize.js: about 19s. Console crashes after 29s. So, I exclude further results.

Bselect performance

Bselect: more than 40s, I got bored counting, so I exclude further results.

And the winner is … Chosen

It is initializes as fastest, being about 1,5x as fast as Select2. Although, Select2 has lot more functionalities and is better maintained. When you only need simple searchable select boxes and mind about performance, Chosen is the best choice. Note that it is only one simple configuration, it might be that in other configurations Select2 is faster than Chosen.

Laravel, Beanstalkd and an overview of queues

In my project I am using Beanstalkd for queue processing. Sometimes jobs get stuck, while I’d like to debug these queue jobs. Mark Needham wrote a great blog about how to get an overview of Beanstalkd jobs.

Connecting

Assuming that Beanstalkd is installed, connect to the console through telnet:

telnet localhost 11300

Getting an overview

Use the command:

stats

You will get output like:

current-jobs-urgent: 0
current-jobs-ready: 2
current-jobs-reserved: 0
current-jobs-delayed: 0
current-jobs-buried: 0
cmd-put: 66
...
current-connections: 6
current-producers: 1
current-workers: 1
current-waiting: 1
total-connections: 58
pid: 15622
version: 1.4.6
rusage-utime: 0.000000
rusage-stime: 0.040002
uptime: 22740
binlog-oldest-index: 0
binlog-current-index: 0
binlog-max-size: 10485760

Listing the first ready job

To see a concrete ready job, use the command:

peek-ready

In terms of Laravel you can get a job result back

{"job":"Illuminate\\Queue\\CallQueuedHandler@call","data":{"...........job\";N;}"}}

If the job got stock, you can clear jobs by pulling in an artisan queue:clear package. Then, you can run the command:

php artisan queue:clear

If your daemon got stock as well, call php artisan queue:restart

Laravel 5.1 logout custom message and redirect to previous page

When you’re logging out in Laravel 5 and 5.1 the AuthenticatesUsers is called and the getLogout method. Since, it’s in the Illuminate directory it’s not nice to write in this file directly. It’s better to rewrite the getLogout method from an Auth\AuthController.

Normally AuthCntroller, it might use this traits:

use AuthenticatesAndRegistersUsers, ThrottlesLogins;

Now we’ll rename the getLogout of the AuthenticatesUsers trait:

use AuthenticatesAndRegistersUsers
    {
        getLogout as authLogout;
    }
    use ThrottlesLogins;

Now we can rewrite the getLogout and still use/inherit the old trait’s class:

    /**
     * Overwrite getLogout method of trait AuthenticatesUsers and calls it again, since it's renamed as $this->authLogout();
     * @return Response
     */
    public function getLogout()
    {
        if (!empty(URL::previous()) && !str_contains(URL::previous(), "auth/"))
        {
            $this->redirectAfterLogout = URL::previous(); // Send back to previous url if possible
        }

        alert()->success('You\'re logged out', 'Logout'); // Send a flash message e.g. with the SweetAlert package: https://github.com/uxweb/sweet-alert
 
        return $this->authLogout(); // rest of the old method of the trait
    }

Laravel 5 socialite with Facebook integration

Would you like to offer a Facebook login functionality next to a regular e-mail based login? This is a tutorial to achieve that with Laravel 5 and the Socialite plugin. This tutorial is based on Matt Stauffer’s tutorial.

First of all pull in Laravel Socialite via composer:

composer require laravel/socialite

Create the users and password_remember migration:

$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('avatar');
$table->string('password', 60);
$table->boolean('is_admin');
$table->string('facebook_id');
$table->rememberToken();
$table->timestamps();

Get your Facebook developer id and secret at: https://developers.facebook.com/.

Insert the Facebook credentials into the app/services.php file:

'facebook' => [
        'client_id' => env('FACEBOOK_ID'),
        'client_secret' => env('FACEBOOK_SECRET'),
        'redirect' => env('FACEBOOK_URL'),
    ],

In my case, I store them in the .env file as environment variables:

FACEBOOK_ID=xxx
FACEBOOK_SECRET=yyy
FACEBOOK_URL=http://myapp.devapp/auth/facebook/callback

Create a users model and make sure that some fields are fillable:

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    use Authenticatable, CanResetPassword;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'password', 'avatar', 'facebook_id'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];
}

So the model and migrations are prepared, if necessary, run your migration:

php artisan migrate

Register a new controller in your routes file (if there’s an auth controller already, do it above the auth controller):

Route::get('/auth/facebook', 'Auth\SocialController@redirectToProvider');
Route::get('/auth/facebook/callback', 'Auth\SocialController@handleProviderCallback');

Create the Facebook Social Auth Controller (app/Http/Controllers/Auth/SocialController.php):

<?php namespace App\Http\Controllers\Auth; use Illuminate\Http\Request; use App\User; use App\Http\Requests; use App\Http\Controllers\Controller; use Auth; use Socialite; class SocialController extends Controller { /** * Redirect the user to the Facebook authentication page. * * @return Response */ public function redirectToProvider() { return Socialite::driver('facebook')->redirect();
    }

    /**
     * Obtain the user information from Facebook.
     *
     * @return Response
     */
    public function handleProviderCallback()
    {
        $user = Socialite::driver('facebook')->user();

        $authUser = $this->findOrCreateUser($user);

        Auth::login($authUser, true);

        return redirect()->back();
    }

    /**
     * Return user if exists; create and return if doesn't
     *
     * @param $fbUser
     * @return User
     */
    private function findOrCreateUser($fbUser)
    {

        if ($authUser = User::where('facebook_id', $fbUser->id)->first()) {
            return $authUser;
        }

        return User::create([
            'name' => $fbUser->name,
            'email' => $fbUser->email,
            'facebook_id' => $fbUser->id,
            'avatar' => $fbUser->avatar
        ]);

    }
}

You can now link to your social auth controller from somewhere in your blade view:

<a class="btn btn-primary" href="{{ action('Auth\SocialController@redirectToProvider') }}"> Login with Facebook</a>

Important safety note

If you’d like to keep the possibility for people to login, make sure that you’ve empty password validation checks, so that people can’t sign in with only Facebook e-mail addresses.

That’s it. Do you’ve additions to this tutorial? Let me know in the comments.

Validating meta title and meta description with jQuery

Would you like to auto-display validation hints when a meta_title field is longer than 55 chars and a meta_description field is longer than 155 chars?

Then you can use this package: jQuery Meta Title and Description Validation.

Setup
1. Have at least one input field named meta_title or meta_description

E.g.

<p>
<input type="text" name="meta_title" placeholder="Meta title">
</p>
<p>
<input type="text" name="meta_description" placeholder="Meta description">
</p>

2. Initialize by including jquery-meta-validation.js

<script type="text/javascript" src="js/jquery-meta-validation.js"></script>

Laravel 5 Admin Middleware (is_admin user check)

Would you like to have middleware that makes sure that only users with an is_admin = 1 status will be able to see the admin section? Then you can use the following code:

app/Http/Middleware/AdminMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;

class AdminMiddleware
{

    /**
     * Handle an incoming request. User must be logged in to do admin check
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (\Auth::user()->is_admin == 1)
        {
            return $next($request);
        }

        return redirect()->guest('/');
    }
}

Make sure you’ll register the middleware as a route in app/Http/Kernel.php

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'admin' => \App\Http\Middleware\AdminMiddleware::class
];

Finally assign this middleware in the routes.php next to the auth middleware, since the admin middleware is an extension to the auth middleware.

App/Http/routes.php

Route::group(['prefix' => 'administration', 'middleware' => ['auth', 'admin']], function()
{
	Route::get('/', 'Admin\HomeController@index');
}

If you’ve suggestions to make this coding more efficient, you’re always welcome to drop a comment below.

Magento sales transactional email – highlight if billing address equals shipping address

Insert this code on the desired place in the .html transactional email (deepter in the locale folder):

{{block type='core/template' area='frontend' template='email/shippingcheck.phtml' order=$order}}

Then create the file in the template you’re using (app/design/frontend/default/default/template/email/shippingcheck.phtml) for example. Insert the following content:

<?php if($this->getData('order')->getShippingAddress()->format('html') != $this->getData('order')->getBillingAddress()->format('html')) { echo $this->getData('order')->getShippingAddress()->format('html'); } else { echo 'The billing address equals the shipping address.'; } ?>

Backup Ubuntu site / Laravel Forge server with Tarsnap

Would you like to backup your Ubuntu server with Tarsnap and also backup your Mysql database? Then follow this steps:

Install Tarsnap

1. Install dependencies

sudo apt-get install build-essential ext2fs-dev zlib1g-dev libssl-dev 

2. Install Tarsnap

Download Tarsnap with this wget:

wget --no-check-certificate https://www.tarsnap.com/download/tarsnap-autoconf-1.0.35.tgz

Now we need to extract, configure, and compile Tarsnap.

tar xfz tarsnap-autoconf-1.0.35.tgz
cd tarsnap-autoconf-1.0.35
./configure
sudo make install clean

3. Configure Tarsnap

Copy the example config to the live config:

sudo mv /usr/local/etc/tarsnap.conf.sample /usr/local/etc/tarsnap.conf

Then create a key, save this key to a USB or something, you can’t reset it.

mkdir ~/.tarsnap
tarsnap-keygen --keyfile /home/youruser/.tarsnap/tarsnap.key --user your@email.com --machine your-machine-name
You’ll be prompted for your Tarsnap password when running tarsnap-keygen.

Now, edit the tarsnap.conf file:

sudo pico /usr/local/etc/tarsnap.conf

Point the keyfile directive to the key file we created a couple steps ago. The top of your tarsnap.conf file should look similar to this now:

### Recommended options
 
# Tarsnap cache directory
cachedir /tmp/tarsnap-cache
 
# Tarsnap key file
keyfile /home/youruser/.tarsnap/tarsnap.key

4. Use Tarsnap to Make a Backup

To create a backup do this:

tarsnap -c -f servername-20140805 /home/forge

I’m using Laravel forge’s home directory. This directory is now backup up to Tarsnap. In the next step we’ll add a backup folder with the latest mysql-database.

Backup Mysql database

Create a folder in /home/forge : backup. Create a file in the folder:

touch /home/forge/makebackup.sh

Insert this information in the file:

#!/bin/sh
TODAY=$(date "+%A");
flock -n ~/.mysqldump mysqldump -u forge -p forge --password=YOURPASSWORD > ~/backup/mysql-latest.sql; 
flock -n ~/.tarsnap.lock tarsnap -c -f "$(uname -n)-$(date +%Y-%m-%d_%H-%M-%S)" ~/ 2>/dev/null; 

Create Cronjob

Let the makebackup.sh be called every x days:

crontab -e

Insert this piece of info:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO={{YOUREMAILHERE}}
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 2 * * * flock -n ~/.makebackup.lock ~/backup/makebackup.sh

To view the backupped files so far:

tarsnap --list-archives | sort

Thanks to Longren.io and thanks to Hypernode

Laravel 5: simple multi-tenant/multi-site model setup (many-to-many relation covered as well)

Laravel multi site multi tenant navigation bar illusatrationLaravel 5 is a brand new version of the popular framework. Unfortunately, there are no good multi-tenant setups for Laravel 5 yet. That’s why I’d decided to create my own simple version as well, based on Eloquent Global Scopes.

In my case I wanted a sites table, with categories that have a many to many relationship. So like:

sites
id | name

categories
id | name

site_category
id | site_id | category_id

So this table structure is a many to many relation. With this setup you can create a multi-site setup with different categories. Site A has categories 1 and 2, Site B has category 3 etc. It’s defined in the model as follows:

App\Site.php

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Site extends Model {

    protected $fillable = ['name', 'domain'];

    public function categories()
    {
        return $this->belongsToMany('App\Category', 'site_category');
    }
}

And the category like:

App\Category.php

<?php namespace App;

use Illuminate\Database\Eloquent\Model;
use App\Traits\TenantableTrait;

class Category extends Model {
	use TenantableTrait;

	/**
	 * The fillables
	 * @var array
	 */
	protected $fillable = ['name', 'description'];

	/**
	 * A category has many sites
	 */
	public function sites()
    {
        return $this->belongsToMany('App\Site', 'site_category');
    }

Notice that this category has the trait TenantableTrait assigned. That is like:

App\Traits\TenantableTrait.php

<?php namespace App\Traits;

use App\TenantScope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;

trait TenantableTrait {

    /**
     * Boot the tenantable trait for the model
     *
     * @return void
     */
    public static function bootTenantableTrait()
    {
        static::addGlobalScope(new TenantScope);
    }

}

And finally, don’t forget the global Eloquent scope:

App\TenantScope.php

&lt;?php namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ScopeInterface;
use Session;

class TenantScope implements ScopeInterface
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        if (Session::has('siteId'))
        {
            $siteId = session('siteId');
          
            $builder->whereHas('sites', function($query) use($siteId)
            {
                $query->where('sites.id', $siteId);
            });
        }
    }

    /**
     * Remove the scope from the given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function remove(Builder $builder, Model $model)
    {
        
        dd('remove called');
    }
}

Now, if you set the site id by session (e.g.) in a controller with:

Session::set('siteId', 1)

A all categories that have a site_category link with site_id=1 will be called. As you see, the remove method still has to be specified, so if you’d like to finish up this script, leave it in the comments.

You can repeat this with site_products or probably even site_category_product (with some finetuning, if that works, let me know below 🙂 ).