<?php
/*
 * @System      : Software Addon Module
 * @developer   : Md.Mamun Khan Sabuj
 * @E-mail      : mamun.sabuj24@gmail.com
 * @datetime    : 10-10-2020
 * @version     : Version 1.0
 */
defined('BASEPATH') or exit('No direct script access allowed');

class Module extends MX_Controller
{

    public function __construct()
    {
        parent::__construct();
        $this->load->model(array(
            'module_model',
            'addons_model'
        ));
         if (! $this->session->userdata('isLogIn'))
            redirect('login'); 

        
    }

    public function index()
    {

        $modulesnames = $this->addons_model->get_downloaded_modules();
        $json_module = $this->addons_model->search_available_modules();

        $live_modules = [];
        if(!empty($json_module)){
            $live_modules = json_decode($json_module);
        }

        $data['live_modules'] = $live_modules;
        $data['downloaded'] = $modulesnames;

        $data['title'] = display('module_list');
        $data['module'] = "addon";
        $data['page'] = "module/list";
        echo Modules::run('template/layout', $data);
    }


    public function upload()
    {

      $this->form_validation->set_rules('purchase_key', display('purchase_key'), 'trim|required');
      if(empty($_FILES)) {
        $this->form_validation->set_rules('module', display('module'), 'trim|required');
      }

      if ($this->form_validation->run() == TRUE) {


          $purchase_key = trim($this->input->post('purchase_key',TRUE));

          $getdata = "item=module&purchase_key=".$purchase_key;

          // Check purchase key 
          $response = $this->addons_model->verify_zip_upload($getdata);

          if(!empty($response) && ($response->status == 'valid')) {

                $config['upload_path'] = './application/modules/';
                $config['allowed_types'] = 'zip|rar|gz';
                $this->load->library('upload');
                $this->upload->initialize($config);
                $overwrite = $this->input->post('overwrite',TRUE);
                $overwrite = (($overwrite != null) ? $overwrite : false);

                if ($this->upload->do_upload('module')) {
                    $data = $this->upload->data();
                    $filePath = $config['upload_path'] . $data['file_name'];

                    $this->load->library('unzip');
                    $result = $this->unzip->extract($filePath, $config['upload_path'], true, $overwrite);
                    if ($result->status) {
                        // Module Json File
                        // $this->create_module_json();

                        $this->session->set_flashdata('message', $result->message);
                    } else {
                        $this->session->set_flashdata('exception', $result->message);
                    }
                } else {
                    $this->session->set_flashdata('exception', $this->upload->display_errors());
                }
                redirect("addon/module");
            }else{
                $this->session->set_flashdata('exception',display("invalid_purchase_key"));
                redirect('addon/module');
            }
        }

        $this->index();
    }


    // public function install()
    // {
    //     $this->form_validation->set_rules('name', display('module_name'), 'required|max_length[50]');
    //     $this->form_validation->set_rules('description', display('description'), 'trim|max_length[500]');
    //     $this->form_validation->set_rules('image', display('image'), 'required|max_length[100]');
    //     $this->form_validation->set_rules('directory', display('module'), 'required|max_length[100]|is_unique[module.directory]');
    //     $this->form_validation->set_message('is_unique', 'The %s is already installed');
    //     /*-----------------------------------*/
    //     $directory = $this->input->post('directory');

    //     /*-----------ADD TO MODULE--------------*/
    //     $moduleData = array(
    //         'id'          => $this->input->post('id',TRUE),
    //         'name'        => $directory,
    //         'description' => $this->input->post('description',FALSE),
    //         'image'       => $this->input->post('image',TRUE),
    //         'directory'   => $directory,
    //         'status'      => 1
    //     );
    //     /*-----------------------------------*/
    //     if ($this->form_validation->run()) {

    //         /*----------MODULE INSTALL------------*/
    //         // IMPORT DATABASE
    //         $dbPath = APPPATH . 'modules/' . $directory . '/assets/data/database.sql';
    //         $configPath = APPPATH . 'modules/' . $directory . '/config/config.php';
    //         if (file_exists($dbPath) && file_exists($configPath)) {
    //             $isi_file = file_get_contents($dbPath);
    //             $string_query = rtrim($isi_file, "\n;");
    //             $array_query = explode(";", $string_query);
    //             $newQuery = null;
    //             $succe = array();
    //             $error = null;
    //             $sl = 1;

    //             @include($configPath);

    //             if (($HmvcConfig[$directory]["_database"] === true) && !empty($HmvcConfig[$directory]["_tables"]) && is_array($HmvcConfig[$directory]["_tables"]) && sizeof($HmvcConfig[$directory]["_tables"]) > 0) {

    //                 // Tables data
    //                 foreach ($HmvcConfig[$directory]["_tables"] as $key => $table) {

    //                     foreach ($array_query as $key2 => $query) {

    //                         if (is_int(strpos($query, "`$table`"))) {
    //                             $succe[] = $table;
    //                             $newQuery .= $query . ";";
    //                             unset($HmvcConfig[$directory]["_tables"][$key]);
    //                             unset($array_query[$key2]);
    //                             break;
    //                         } else {
    //                             $error .= "`$table`";
    //                             unset($HmvcConfig[$directory]["_tables"][$key]);
    //                             break;
    //                         }
    //                     }
    //                 }

    //                 if (strlen($error) > 0) {
    //                     $this->session->set_flashdata('exception', $error . display('tables_are_not_available_in_database'));
    //                     redirect("addon/module");
    //                 } else {
    //                     $n_query = rtrim($newQuery, "\n;");
    //                     $n_query = explode(";", $n_query);
    //                     $i = 0;
    //                     foreach ($n_query as $sql) {
    //                         if (!$this->db->table_exists($succe[$i++])) {
    //                             $this->db->query("SET FOREIGN_KEY_CHECKS = 0");
    //                             $this->db->query($sql);
    //                             $this->db->query("SET FOREIGN_KEY_CHECKS = 1");
    //                         }
    //                     }

    //                     /*----------ADD TO MODULE ------------*/
    //                     if ($this->module_model->create($moduleData)) {
    //                         // add a install flag
    //                         @file_put_contents(
    //                             APPPATH . 'modules/' . $directory . '/assets/data/env',
    //                             date('d-m-Y')
    //                         );

    //                         $this->session->set_flashdata('message', display('module_added_successfully'));
    //                     } else {
    //                         $this->session->set_flashdata('exception', display('please_try_again'));
    //                     }
    //                 }
    //             } else if ($HmvcConfig[$directory]["_database"] === false) {
    //                 /*----------ADD TO MODULE ------------*/
    //                 if ($this->module_model->create($moduleData)) {
    //                     // add a install flag
    //                     @file_put_contents(
    //                         APPPATH . 'modules/' . $directory . '/assets/data/env',
    //                         date('d-m-Y')
    //                     );

    //                     $this->session->set_flashdata('message', display('module_added_successfully'));
    //                 } else {
    //                     $this->session->set_flashdata('exception', display('please_try_again'));
    //                 }
    //             } else {
    //                 $this->session->set_flashdata('exception', display('no_tables_are_registered_in_config'));
    //             }

    //              // Data insert/update into existing table
                
    //             if ($HmvcConfig[$directory]["_extra_query"] === true) {
    //                 $extra_query = APPPATH . 'modules/' . $directory . '/assets/data/install.sql';
    //                 if (file_exists($extra_query) && file_exists($configPath)) {

    //                     $equery_file = file_get_contents($extra_query);
    //                     $equery_string = trim($equery_file);
                        
    //                     if(!empty($equery_string))
    //                     {
    //                         $equery_list = explode(";", $equery_string);
    //                         $this->db->trans_start();
    //                         foreach ($equery_list as $equery_item) {
    //                             if(!empty($equery_item)){
    //                                 $this->db->query($equery_item);
    //                             }
    //                         }
    //                         $this->db->trans_complete();
    //                     }
    //                 }
    //             }


    //         } else {
    //             $this->session->set_flashdata('exception', display('please_try_again'));
    //         }
    //         redirect("addon/module");

    //     } else {
    //         $this->session->set_flashdata('exception', validation_errors());
    //     }
    //     redirect("addon/module");
    // }

// install module


public function install()
{
    $this->form_validation->set_rules('name', display('module_name'), 'required|max_length[50]');
    $this->form_validation->set_rules('description', display('description'), 'trim|max_length[500]');
    $this->form_validation->set_rules('image', display('image'), 'required|max_length[100]');
    $this->form_validation->set_rules('directory', display('module'), 'required|max_length[100]|is_unique[module.directory]');
    $this->form_validation->set_message('is_unique', 'The %s is already installed');

    $directory = $this->input->post('directory');

    // Module data
    $moduleData = array(
        'id'          => $this->input->post('id', TRUE),
        'name'        => $directory,
        'description' => $this->input->post('description', FALSE),
        'image'       => $this->input->post('image', TRUE),
        'directory'   => $directory,
        'status'      => 1
    );

    if ($this->form_validation->run()) {

        // Load the menu configuration
        $menuPath = APPPATH . 'modules/' . $directory . '/config/menu.php';
        if (file_exists($menuPath)) {
            include($menuPath);

            // Check if the menu is defined
            if (isset($HmvcMenu2[$directory])) {
                $menuData = $HmvcMenu2[$directory];

                // Iterate through menu items and insert into language table
                foreach ($menuData as $key => $item) {
                    if ($key === 'icon') {
                        continue; // Skip the icon key
                    }

                    // Check if the phrase already exists
                    $exists = $this->db->get_where('language', ['phrase' => $key])->row();
                    if (!$exists) {
                        $data = array(
                            'phrase'  => $key,
                            'english' => ucwords(str_replace('_', ' ', $key)), // Convert key to readable text
                        );
                        $this->db->insert('language', $data);
                    }
                }
            }
        }

        // Process the database and module creation
        $dbPath = APPPATH . 'modules/' . $directory . '/assets/data/database.sql';
        $configPath = APPPATH . 'modules/' . $directory . '/config/config.php';

        if (file_exists($dbPath) && file_exists($configPath)) {
            $isi_file = file_get_contents($dbPath);
            $string_query = rtrim($isi_file, "\n;");
            $array_query = explode(";", $string_query);
            $newQuery = null;
            $succe = array();
            $error = null;

            @include($configPath);

            if (($HmvcConfig[$directory]["_database"] === true) && !empty($HmvcConfig[$directory]["_tables"])) {
                foreach ($HmvcConfig[$directory]["_tables"] as $key => $table) {
                    foreach ($array_query as $key2 => $query) {
                        if (is_int(strpos($query, "`$table`"))) {
                            $succe[] = $table;
                            $newQuery .= $query . ";";
                            unset($HmvcConfig[$directory]["_tables"][$key]);
                            unset($array_query[$key2]);
                            break;
                        } else {
                            $error .= "`$table`";
                            unset($HmvcConfig[$directory]["_tables"][$key]);
                            break;
                        }
                    }
                }

                if (!empty($error)) {
                    $this->session->set_flashdata('exception', $error . display('tables_are_not_available_in_database'));
                    redirect("addon/module");
                } else {
                    $n_query = rtrim($newQuery, "\n;");
                    $n_query = explode(";", $n_query);
                    $i = 0;
                    foreach ($n_query as $sql) {
                        if (!$this->db->table_exists($succe[$i++])) {
                            $this->db->query("SET FOREIGN_KEY_CHECKS = 0");
                            $this->db->query($sql);
                            $this->db->query("SET FOREIGN_KEY_CHECKS = 1");
                        }
                    }

                    // Add to module
                    if ($this->module_model->create($moduleData)) {
                        @file_put_contents(
                            APPPATH . 'modules/' . $directory . '/assets/data/env',
                            date('d-m-Y')
                        );

                        $this->session->set_flashdata('message', display('module_added_successfully'));
                    } else {
                        $this->session->set_flashdata('exception', display('please_try_again'));
                    }
                }
            } else if ($HmvcConfig[$directory]["_database"] === false) {
                // Add to module
                if ($this->module_model->create($moduleData)) {
                    @file_put_contents(
                        APPPATH . 'modules/' . $directory . '/assets/data/env',
                        date('d-m-Y')
                    );

                    $this->session->set_flashdata('message', display('module_added_successfully'));
                } else {
                    $this->session->set_flashdata('exception', display('please_try_again'));
                }
            } else {
                $this->session->set_flashdata('exception', display('no_tables_are_registered_in_config'));
            }

            // Insert extra queries
            if ($HmvcConfig[$directory]["_extra_query"] === true) {
                $extra_query = APPPATH . 'modules/' . $directory . '/assets/data/install.sql';
                if (file_exists($extra_query)) {
                    $equery_file = file_get_contents($extra_query);
                    $equery_string = trim($equery_file);
                    if (!empty($equery_string)) {
                        $equery_list = explode(";", $equery_string);
                        $this->db->trans_start();
                        foreach ($equery_list as $equery_item) {
                            if (!empty($equery_item)) {
                                $this->db->query($equery_item);
                            }
                        }
                        $this->db->trans_complete();
                    }
                }
            }
        } else {
            $this->session->set_flashdata('exception', display('please_try_again'));
        }
        redirect("addon/module");
    } else {
        $this->session->set_flashdata('exception', validation_errors());
    }
    redirect("addon/module");
}




    // Uninstall Module
    public function uninstall($dirPath = null, $action = null)
    {
        $directory = $dirPath;
        $basePath = "application/modules/";
        $dirPath = $basePath . urldecode($dirPath);

        if (is_dir($dirPath) && $dirPath != $basePath) {

            /*-------DELETE MODULE DATABASE---------*/
            $configPath = APPPATH . 'modules/' . $directory . '/config/config.php';
            if (file_exists($configPath)) {

                @include($configPath);

                if (!empty($HmvcConfig[$directory]["_tables"]) && is_array($HmvcConfig[$directory]["_tables"]) && sizeof($HmvcConfig[$directory]["_tables"]) > 0) {

                    foreach ($HmvcConfig[$directory]["_tables"] as $table) {
                        if ($this->db->table_exists($table)) {
                            $this->db->query("DROP TABLE `$table`");
                        }
                    }
                }
            }


            if ($action == "delete") {
                $this->delete_dir($dirPath);
            }
            /*-------DELETE FROM MODULE LIST---------*/
            $this->module_model->delete_by_directory($directory);
            //delete the install flag
            if (file_exists(APPPATH . 'modules/' . $directory . '/assets/data/env'))
                @unlink(APPPATH . 'modules/' . $directory . '/assets/data/env');

            $this->session->set_flashdata('message', display('delete_successfully'));


        } else if (is_file($dirPath) && $dirPath != $basePath) {
            if (unlink($dirPath)) {
                $this->session->set_flashdata('message', display('delete_successfully'));
            } else {
                $this->session->set_flashdata('exception', display('please_try_again'));
            }
        } else {
            $this->session->set_flashdata('exception', display('please_try_again'));
        }

        redirect($_SERVER['HTTP_REFERER']);
    }

    // Change Module Status
    public function status($id = null, $action = null)
    {
        $action = ($action == 'active' ? 1 : 0);

        $data = array(
            'id' => $id,
            'status' => $action
        );

        if ($this->module_model->update($data)) {
            $this->session->set_flashdata('message', display('update_successfully'));
        } else {
            $this->session->set_flashdata('exception', display('please_try_again'));
        }

        redirect($_SERVER['HTTP_REFERER']);
    }


    public function delete_dir($dirPath)
    {
        $dir = opendir($dirPath);
        while (false !== ($file = readdir($dir))) {
            if (($file != '.') && ($file != '..')) {
                if (is_dir($dirPath . '/' . $file)) {
                    $this->delete_dir($dirPath . '/' . $file);
                } else {
                    unlink($dirPath . '/' . $file);
                }
            }
        }
        closedir($dir);
        rmdir($dirPath);
        // Module Json File
        
        return true;
    }

      // Download Module
    public function download_module(){

        $data['title'] =   display('download');
        $data['module'] = "addon";
        $data['page'] = "module/download";
        echo Modules::run('template/layout', $data);
    }

    // Unzip Files
    private function unzip_files($zip_file)
    {

      $path = pathinfo( realpath( $zip_file ), PATHINFO_DIRNAME );

      $zip = new ZipArchive;
      $res = $zip->open($zip_file);
      if ($res === TRUE) {
          $zip->extractTo( $path );
          $zip->close();
      }
      return $res;

    }


    // Verify Module
    public function verify_download_request() {


      $purchase_key = $this->input->post('purchase_key',TRUE);
      $itemtype = $this->input->post('itemtype',TRUE);

      if(!empty($purchase_key) && !empty($itemtype)) {

        $getdata = "item=module&purchase_key=".trim($purchase_key);

        $result = $this->addons_model->send_download_request($getdata);


          if ($result->status == 'valid') {

            $filename = "New_module_".time().'.zip';
            $destination = APPPATH.'modules/'.$filename;
            $copydata = copy($result->download_url, $destination);
            if($copydata) 
            {
              // unzip files
              $unzip = $this->unzip_files($destination);
              if($unzip) {
                unlink($destination);
             $m_p_data = array(
                'identity'     => $result->identity,
                'purchase_key' => $purchase_key,
             );
             $this->db->insert('module_purchase_key',$m_p_data);
                // Module Json File
                

                $this->session->set_flashdata('message', "Downloaded Successfully");
                echo TRUE;
                exit();
              
              }

            }
          } 
      } 
      $this->session->set_flashdata('exception', "Invalid Request");
      echo false;

    }


}
