Your IP : 216.73.216.79


Current Path : /var/www/html/maiwp.bak/console/controllers/
Upload File :
Current File : /var/www/html/maiwp.bak/console/controllers/UserFrontendController.php

<?php

namespace console\controllers;

use Yii;
use yii\console\Controller;
use console\models\UserIntegration;
use yii\db\Expression;

/**
 * Sync user with hrms user
 */
class UserFrontendController extends Controller
{
    /**
     * @property debug
     **/
    const DEBUG_LEVEL = 'ALL';

    /**
     * @method initialize
     **/
    public function init()
    {
    }

    /***
     * Main action sync user with hrms api 
     * 
     ***/
    public function actionSyncUser()
    {
        $track = new UserIntegration();

        $track->start = date('Y-m-d H:i:s');

        try {

            $this->syncUser(function ($updated, $inserted) use (&$track) {
                $track->updated  = $updated;

                $track->inserted = $inserted;
            });

            $track->end = date('Y-m-d H:i:s');

            $track->status = 1;

            $track->save();
        } catch (\Throwable $t) {

            echo 'Error:--------------------------------------------'
                . PHP_EOL
                . $t->getLine() . PHP_EOL
                . $t->getFile() . PHP_EOL
                . $t->getMessage() . PHP_EOL;

            $track->status = 0;

            $track->errors = $t->getFile() . ' | ' . $t->getLine() . ' | ' . $t->getMessage();

            $track->end = date('Y-m-d H:i:s');

            $track->save();
        }
    }

    /**
     * Sync user between content_directory and frontend_user
     * @param object $data user object from api
     * @param callback $track_callback callback for tracking record
     **/
    private function syncUser($track_callback)
    {
        try {
            $record_update = 0;
            $record_insert = 0;

            /** create reflection **/
            $directory_user = $this->createReflectionInstance($this->modelDirectory());

            $frontend_user  = $this->createReflectionInstance($this->modelFrontendUser());

            /** get all active directory user **/
            $all_dir_user = $directory_user->find()->where([
                'employee_status' => 'Y'
            ])->all();

            /** #1.  existing email issue, there are duplicate email to prevent this, temp variable is used then it will be compare with the running data in the loop **/
            $temp_emails = [];
            $temp_email_inc = 0;

            foreach ($all_dir_user as $dir_user) {

                /** debug **/
                if (self::DEBUG_LEVEL == 'ALL') {
                    echo  '[' . $dir_user->employee_number . ']' . PHP_EOL;
                }

                /** check first if user already exist **/
                $exist_user = $frontend_user->find()->where([
                    'employee_no' => $dir_user->employee_number,
                ])->one();

                if (empty($exist_user)) {

                    /** #1. checking if email already exist in temporary var **/
                    if (in_array($dir_user->employee_email, $temp_emails)) {
                        if (self::DEBUG_LEVEL == 'ALL' || self::DEBUG_LEVEL == 'INSERT') {
                            echo  'Existing Email:- ' . $dir_user->employee_email . PHP_EOL;
                        }
                        continue; // skiping if email already exist
                    }

                    //insert user // return back record inserted
                    $this->insertUser($dir_user);
                    $record_insert++;
                } else {
                    //update user // return back record updated
                    $this->updateUser($exist_user, $dir_user);
                    $record_update++;
                }

                /** #1. temporary variable set in the last foreach segment, if this part put into the if else insert block it will be thrown an error for update **/
                $temp_emails[$temp_email_inc] = $dir_user->employee_email;
                $temp_email_inc++;
            }

            if (is_callable($track_callback)) {
                $track_callback($record_update, $record_insert);
            }
        } catch (\Throwable $t) {
            throw $t;
        }
    }

    /**
     * Update user in db
     **/
    private function updateUser($exist_user, $user_row)
    {
        try {
            $need_update = $this->compareExisting($exist_user->toArray(), $user_row);

            /** time tracked **/
            /** static required field **/
            $need_update['updated_at'] = date('Y-m-d H:i:s');

            $exist_user->attributes = $need_update;

            if (!$exist_user->save()) {
                throw new \Exception("Cannot update user information " . $user_row->employee_number . ' | ' . json_encode($exist_user->errors));
            }
        } catch (\Throwable $t) {
            throw $t;
        }
    }


    /**
     * insert user to db
     **/
    private function insertUser($user_row)
    {
        try {
            if (self::DEBUG_LEVEL == 'ALL' || self::DEBUG_LEVEL == 'INSERT') {
                echo  '===================[' . $user_row->employee_number . ']==================' . PHP_EOL;
            }

            $create   = [];

            /** required static property **/
            $create['role']   = 'pengguna';
            $create['status'] = 1;
            $create['created_at'] = date('Y-m-d H:i:s');
            $create['created_by'] = 99;
            $create['password_hash'] = $this->generatePassword($user_row->employee_number);

            foreach ($this->columnMap() as $columnKey => $column_prop) {
                if (isset($user_row->{$columnKey})) {

                    /** input transform **/
                    $data = $this->{$column_prop['type']}($user_row->{$columnKey}, $create);

                    /** set data array **/
                    $create[$column_prop['field']] = $data;
                }
            }

            /** create a new instance of model **/
            $model  = $this->createReflectionInstance($this->modelFrontendUser());

            /** time tracked **/

            /** insert **/
            $model->attributes = $create;

            if (!$model->save()) {
                throw new \Exception("Cannot create user information " . $user_row->employee_number . " | " . json_encode($model->errors));
            }

            if (self::DEBUG_LEVEL == 'ALL' || self::DEBUG_LEVEL == 'INSERT') {
                echo '' . PHP_EOL;
                print_r($create) . PHP_EOL;
                echo '' . PHP_EOL;
            }
        } catch (\Throwable $t) {
            throw $t;
        }
    }

    /**
     * compare existing data for update, match field mapping with every row of user data
     **/
    private function compareExisting($existing_user, $user_row)
    {
        $temp_arr = [];

        if (self::DEBUG_LEVEL == 'ALL' || self::DEBUG_LEVEL == 'UPDATE') {
            echo  '===================[' . $user_row->employee_number . ']==================' . PHP_EOL;
        }

        $existing_field   = "";
        foreach ($this->columnMap() as $column_key => $column_prop) {
            /** only grab existing field in column mapping **/
            if (
                in_array($column_prop['field'], array_keys($existing_user))
                &&
                !empty($user_row->{$column_key})
            ) {

                $existing_field = $existing_user[$column_prop['field']];

                /** filter base on type **/
                $data = $this->{$column_prop['type']}($user_row->{$column_key}, $existing_user);

                if ($existing_field != $data) {

                    if (!empty($data))
                        $temp_arr[$column_prop['field']] = $data;

                    if (self::DEBUG_LEVEL == 'ALL' || self::DEBUG_LEVEL == 'UPDATE') {
                        echo '' . PHP_EOL;
                        echo $column_prop['field'] . PHP_EOL;
                        echo 'Existing :-' . $existing_field . PHP_EOL;
                        echo 'Payload  :-' . $data . PHP_EOL;
                        echo '' . PHP_EOL;
                    }
                }
            }
        }

        return $temp_arr;
    }

    /***
     * Column mapping from api, and field form db
     **/
    private function columnMap()
    {
        return [
            "employee_number" => [
                "field" => "employee_no",
                "type" => "string"
            ],
            "employee_email" => [
                "field" => "username",
                "type" => "string"
            ],
            "employee_name" => [
                "field" => "fullname",
                "type" => "string"
            ],
            "employee_phone" => [
                "field" => "mobile_no",
                "type" => "string"
            ],
            "employee_image" => [
                "field" => "img_url",
                "type" => "image"
            ]
        ];
    }

    /**
     * Class name from frontend user
     **/
    private function createReflectionInstance($model)
    {
        $r = new \ReflectionClass($model);

        $instance =  $r->newInstanceWithoutConstructor();

        return $instance;
    }

    /**
     * String filter
     **/
    private function string($val)
    {
        return $val;
        // return filter_var($val, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    }

    /**
     * image filter, download the image and return the filename
     **/
    private function image($val)
    {
        try {
            return $val;
        } catch (\Throwable $t) {
            echo $t->getMessage();
            // throw $t;
        }
    }

    private function generatePassword($password)
    {
        return Yii::$app->getSecurity()->generatePasswordHash($password);
    }

    /**
     * Class name from content directory
     **/
    private function modelDirectory()
    {
        return \backend\modules\contentDirectory\models\ContentDirectory::class;
    }

    /**
     * Class name from frontend user
     **/
    private function modelFrontendUser()
    {
        return \backend\modules\fruserdynav2\models\FrontendUser::class;
    }
}