<?php
defined('BASEPATH') or exit('No direct script access allowed');

/* load the MX_Loader class */
require APPPATH . 'third_party/MX/Loader.php';

class Cf_Loader extends MX_Loader
{
    /**
     * Load hooks classes
     *
     * some requirenments:
     *  - file must be in hooks folder inside app
     *  - file must have the same name as app + _hooks.php
     *
     *
     * @param object $CI     - current codeigniter instanse - cf_controller
     * @param type   $module - module name for load
     * @param array  $params - additional params
     */

    public function hookload($CI, $module, $params = null)
    {
        is_array($module) ? ([$module, $params] = each($module)) : ($params = null);

        /* get the requested controller class name */
        $alias = strtolower(basename($module));

        // create or return an existing controller from the registry
        if (!isset(Modules::$registry[$alias])) {
            // find the hook class
            $hook_info = $this->locate_hooks(explode('/', $module));
            // hooks file cannot be located
            if (!is_array($hook_info) || empty($hook_info['hook_class'])) {
                return;
            } else {
                $class = $hook_info['hook_class'];
            }

            // set the module directory
            $path = $hook_info['hook_path'];

            // load the controller class
            $class = $class . '_hooks';

            Modules::load_file($class, $path);

            $controller = ucfirst($class);

            Modules::$registry[$alias] = new $controller($params);
        }

        $CI->load->module($module);
    }

    /** Locate the hooks class
     *
     * trying to find class based on app name provided like: modules/appname/hooks/appname_hooks.php
     *
     * @param type $segments
     * @return array or false if not found
     */
    public function locate_hooks($segments)
    {
        $hooksFolder = 'hooks';

        $this->module = '';
        $this->directory = '';
        $ext = $this->config->item('controller_suffix') . EXT;

        /* use module route if available */
        if (isset($segments[0]) and ($routes = Modules::parse_routes($segments[0], implode('/', $segments)))) {
            $segments = $routes;
        }

        /* get the segments array elements */
        [$module, $directory, $controller] = array_pad($segments, 3, null);

        /* check modules */
        foreach (Modules::$locations as $location => $offset) {
            /* hooks exists? */
            if (is_dir($source = $location . $module . '/' . $hooksFolder . '/')) {
                if (is_file($source . $module . '_hooks.php')) {
                    return [
                        'hook_class' => $module,
                        'hook_path' => $source,
                    ];
                }
            }
        }
        return false;
    }

    /**
     *  This function is to override CI's default active record.
     *  Temporary selection until the active record class has fix in stable release
     * @param type $params
     * @param type $return
     * @param type $active_record
     * @return boolean
     */
    public function database($params = '', $return = false, $active_record = null)
    {
        // Grab the super object
        $CI = &get_instance();

        // Do we even need to load the database class?
        if (
            class_exists('CI_DB') and
            $return == false and
            $active_record == null and
            isset($CI->db) and
            is_object($CI->db)
        ) {
            return false;
        }

        // Check if custom DB file exists, else include core one
        if (file_exists(APPPATH . 'core/' . config_item('subclass_prefix') . 'DB' . EXT)) {
            require_once APPPATH . 'core/' . config_item('subclass_prefix') . 'DB' . EXT;
        } else {
            require_once BASEPATH . 'database/DB' . EXT;
        }

        $db = DB($params, $active_record);

        $custom_driver = config_item('subclass_prefix') . 'DB_' . $db->dbdriver . '_driver';
        $custom_driver_file = APPPATH . 'core/' . $custom_driver . EXT;

        if (file_exists($custom_driver_file)) {
            require_once $custom_driver_file;
            $db = new $custom_driver(get_object_vars($db));
        }

        if ($return === true) {
            return $db;
        }

        // Initialize the db variable. Needed to prevent
        // reference errors with some configurations
        $CI->db = '';

        // Load the DB class
        $CI->db = $db;
    }
}
