/home/mip/mip/app/Modules/Likod/Repositories/Clients/Clients/ClientRepository.php
<?php

namespace QxCMS\Modules\Likod\Repositories\Clients\Clients;
use Illuminate\Support\Str;
use QxCMS\Modules\AbstractRepository;
use QxCMS\Modules\Likod\Repositories\Clients\Clients\ClientRepositoryInterface;
use QxCMS\Modules\Likod\Models\Clients\Client;
use QxCMS\Modules\Likod\Models\Clients\User;
use QxCMS\Modules\Client\Models\Settings\Roles\Permission;
use QxCMS\Modules\Likod\Models\Developer\ClientModule;
use DB;
use Artisan;
use Config;
use Illuminate\Support\Arr;

class ClientRepository extends AbstractRepository implements ClientRepositoryInterface
{
    protected $model;
    protected $user;
    protected $permission;
    protected $clientModule;
    protected $db_prefix = "";

    function __construct(Client $model, User $user, Permission $permission, ClientModule $clientModule)
    {
        $this->model = $model;
        $this->user = $user;
        $this->permission = $permission;
        $this->clientModule = $clientModule;
        $this->db_prefix = env('DB_PREFIX', 'qxcms_');
    }

    public function create(array $request)
    {
        $client = $this->model->fill($this->makeClient($request));
        $client->save();
        $client->users()->create($this->makeUser($request, $client->id));
        $this->makeDB($client->database_name);
        $this->makeMigration($client);
        $this->makeRolePermission($client);
        return $client;
    }

    public function makeClient(array $request)
    {
        if (Str::endsWith($request['database_name'], 'db')) {
            $request['root_dir'] = substr($request['database_name'], 0, -2);
        } else {
            $request['root_dir'] = $request['database_name'];
        }
        return $request;
    }

    public function makeUser(array $request, $client_id)
    {
        return [
            'client_id' => $client_id,
            'name' => $request['name'],
            'username' => '',
            'email' => $request['email'],
            'password' => bcrypt($request['password']),
            'type_id' => 1,
            'role_id' => 2,
            'status' => $request['status'], 
        ];
    }

    public function makeDB($name)
    {
        if ($name != "") 
        {
            DB::statement('CREATE DATABASE IF NOT EXISTS '.$this->db_prefix.$name.';');
        }       
    }

    public function makeMigration($client)
    {
        $this->setConfig($client);
        return Artisan::call('migrate', array('--database'=>'client','--path'=>'database/migrations/client'));
    }

    public function makeRolePermission($client)
    {
        $this->setConfig($client);
        $clientModules = $this->clientModule->all();
        foreach ($clientModules as $clientModule) {
            $cmode = json_decode(json_encode($clientModule), true);
            $this->addPermission($cmode, 1);
            $this->addPermission($cmode, 2);
        }
        return $clientModules;
    }

    public function addPermission(array $clientModules, $role_id)
    {
        $id = $clientModules['id'];
        $this->permission->where('menu_id', $id)->where('role_id', $role_id)->delete();
        $this->permission->create($this->permissionRequest($clientModules, $role_id));
    }

    public function permissionRequest(array $clientModules, $role_id)
    {
        return $permissions = [
                'role_id' => $role_id,
                'menu_id' =>  $clientModules['id'],
                'can_access' => $clientModules['show_menu'],
                'can_create' => $clientModules['has_create'],
                'can_update' => $clientModules['has_update'],
                'can_delete' => $clientModules['has_delete'],
                'can_export' => $clientModules['has_export'],
                'can_import' => $clientModules['has_import'],
                'can_print' => $clientModules['has_print']
        ];
    }

    public function update($id, array $request, $client_config = true)
    {
        $client = $this->findById($id);
        $client->fill($this->getEditable($request));
        return $this->affectedRows($client, $client_config);
    }

    public function getEditable(array $request)
    {
        return Arr::except($request, ['database_name', 'root_dir', 'cpanel_email']);
    }

    public function affectedRows(Client $client, $client_config) 
    {
        if(count($client->getDirty()) > 0) {
            $client->save();
            session()->flash('success', 'Successfully updated.');
            if(!$client_config) {
                $this->logUser(85, 'Edit', auth('client')->user()->id, $client->id);
            }
        }
        return $client;
    }

    public function mainUser($id)
    {
        return $this->findById($id)->users()->where('type_id', 1)->first();
    }
}