<?php
 
namespace App;
 
trait FullTextSearch
{
    /**
     * Replaces spaces with full text search wildcards
     *
     * @param string $term
     * @return string
     */
    protected function fullTextWildcards($term)
    {
        // removing symbols used by MySQL
        $reservedSymbols = ['-', '+', '<', '>', '@', '(', ')', '~', '.'];
        $term = str_replace($reservedSymbols, ' ', $term);
 
        $words = explode(' ', $term);
 
        foreach($words as $key => $word) {
            if(strlen($word) < 3) {
                $words[$key] = '+' . $word . '*';
            }
        }
 
        $searchTerm = implode( ' ', $words);
 
        return $searchTerm;
    }
 
    /**
     * Scope a query that matches a full text search of term.
     * Compatible with both MySQL and SQLite.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $term
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeSearch($query, $term)
    {   
        $driver = config('database.default');
        $columns = $this->searchable;

        // SQLite compatible search using LIKE
        if ($driver === 'sqlite') {
            return $query->where(function($q) use ($columns, $term) {
                foreach ($columns as $column) {
                    $q->orWhere($column, 'LIKE', '%' . $term . '%');
                }
            });
        }

        // MySQL search
        $columnStr = implode(',', $columns);

        if(!ctype_space($term)) {
            return $query->whereRaw("CONCAT($columnStr) LIKE '%".$term."%'") ;
        }

        return $query->whereRaw("MATCH ({$columnStr}) AGAINST (? IN NATURAL LANGUAGE MODE)" , $this->fullTextWildcards($term));
    }
}
