diff --git a/hungng/HungNG_CI_Base_Controllers.php b/hungng/HungNG_CI_Base_Controllers.php index 21c61be..611943c 100644 --- a/hungng/HungNG_CI_Base_Controllers.php +++ b/hungng/HungNG_CI_Base_Controllers.php @@ -559,7 +559,7 @@ protected function command_clean_cache_apc() * @copyright: 713uk13m * @time : 09/01/2021 52:11 */ - protected function command_create_encryption_key(): void + protected function command_create_encryption_key() { if (is_cli()) { $this->load->library('encryption'); diff --git a/hungng/HungNG_CI_Base_Module.php b/hungng/HungNG_CI_Base_Module.php index 4a527e5..1a99026 100644 --- a/hungng/HungNG_CI_Base_Module.php +++ b/hungng/HungNG_CI_Base_Module.php @@ -559,7 +559,7 @@ protected function command_clean_cache_apc() * @copyright: 713uk13m * @time : 09/01/2021 52:11 */ - protected function command_create_encryption_key(): void + protected function command_create_encryption_key() { if (is_cli()) { $this->load->library('encryption'); diff --git a/hungng/HungNG_Custom_Based_model.php b/hungng/HungNG_Custom_Based_model.php index 11c6830..af4061c 100644 --- a/hungng/HungNG_Custom_Based_model.php +++ b/hungng/HungNG_Custom_Based_model.php @@ -10,1414 +10,1414 @@ * Time: 13:50 */ if (!class_exists('HungNG_Custom_Based_model')) { - /** - * Class HungNA_Based_model - * - * @author 713uk13m - * @copyright 713uk13m - * - * @property CI_Benchmark $benchmark This class enables you to mark points and calculate the time difference between them. Memory consumption can also be displayed. - * @property CI_Calendar $calendar This class enables the creation of calendars - * @property CI_Cache $cache Caching Class - * @property CI_Cart $cart Shopping Cart Class - * @property CI_Config $config This class contains functions that enable config files to be managed - * @property CI_Controller $controller This class object is the super class that every library in CodeIgniter will be assigned to - * @property CI_DB_forge $dbforge Database Forge Class - * @property CI_DB_pdo_driver|CI_DB_query_builder|CI_DB_driver $db This is the platform-independent base Query Builder implementation class - * @property CI_DB_utility $dbutil Database Utility Class - * @property CI_Driver_Library $driver Driver Library Class - * @property CI_Email $email Permits email to be sent using Mail, Sendmail, or SMTP - * @property CI_Encrypt $encrypt Provides two-way keyed encoding using Mcrypt - * @property CI_Encryption $encryption Provides two-way keyed encryption via PHP's MCrypt and/or OpenSSL extensions - * @property CI_Exceptions $exceptions Exceptions Class - * @property CI_Form_validation $form_validation Form Validation Class - * @property CI_FTP $ftp FTP Class - * @property CI_Hooks $hooks Provides a mechanism to extend the base system without hacking - * @property CI_Image_lib $image_lib Image Manipulation class - * @property CI_Input $input Pre-processes global input data for security - * @property CI_Javascript $javascript Javascript Class - * @property CI_Jquery $jquery Jquery Class - * @property CI_Lang $lang Language Class - * @property CI_Loader $load Loads framework components - * @property CI_Log $log Logging Class - * @property CI_Migration $migration All migrations should implement this, forces up() and down() and gives access to the CI super-global - * @property CI_Model $model CodeIgniter Model Class - * @property CI_Output $output Responsible for sending final output to the browser - * @property CI_Pagination $pagination Pagination Class - * @property CI_Parser $parser Parser Class - * @property CI_Profiler $profiler This class enables you to display benchmark, query, and other data in order to help with debugging and optimization. - * @property CI_Router $router Parses URIs and determines routing - * @property CI_Security $security Security Class - * @property CI_Session $session Session Class - * @property CI_Table $table Lets you create tables manually or from database result objects, or arrays - * @property CI_Trackback $trackback Trackback Sending/Receiving Class - * @property CI_Typography $typography Typography Class - * @property CI_Unit_test $unit Simple testing class - * @property CI_Upload $upload File Uploading Class - * @property CI_URI $uri Parses URIs and determines routing - * @property CI_User_agent $agent Identifies the platform, browser, robot, or mobile device of the browsing agent - * @property CI_Xmlrpc $xmlrpc XML-RPC request handler class - * @property CI_Xmlrpcs $xmlrpcs XML-RPC server class - * @property CI_Zip $zip Zip Compression Class - * @property CI_Utf8 $utf8 Provides support for UTF-8 environments - */ - class HungNG_Custom_Based_model extends CI_Model - { - const OPERATOR_EQUAL_TO = '='; - const OPERATOR_NOT_EQUAL_TO = '!='; - const OPERATOR_LESS_THAN = '<'; - const OPERATOR_LESS_THAN_OR_EQUAL_TO = '<='; - const OPERATOR_GREATER_THAN = '>'; - const OPERATOR_GREATER_THAN_OR_EQUAL_TO = '>='; - const OPERATOR_IS_SPACESHIP = '<=>'; - const OPERATOR_IS_IN = 'IN'; - const OPERATOR_IS_LIKE = 'LIKE'; - const OPERATOR_IS_LIKE_BINARY = 'LIKE BINARY'; - const OPERATOR_IS_ILIKE = 'ilike'; - const OPERATOR_IS_NOT_LIKE = 'NOT LIKE'; - const OPERATOR_IS_NULL = 'IS NULL'; - const OPERATOR_IS_NOT_NULL = 'IS NOT NULL'; - const ORDER_ASCENDING = 'ASC'; - const ORDER_DESCENDING = 'DESC'; - const ORDER_RANDOM = 'RAND'; - const DEFAULT_STATUS_IS_ACTIVE = 1; - const DEFAULT_STATUS_IS_DE_ACTIVE = 0; - - /** @var \CI_DB_query_builder $db */ - protected $db; - - /** @var string $tableName */ - protected $tableName; - - /** @var string $primary_key */ - protected $primary_key; - - /** @var string $is_not $is_not */ - protected $is_not; - - /** @var string $or_higher */ - protected $or_higher; - - /** @var string $is_higher */ - protected $is_higher; - - /** @var string $or_smaller */ - protected $or_smaller; - - /** @var string $is_smaller */ - protected $is_smaller; - - /** @var array $field */ - protected $field = array(); - - /** @var string $start_time */ - protected $start_time; - - /** @var string $end_time */ - protected $end_time; - - /** @var string $created_at */ - protected $created_at; - - /** @var string $updated_at */ - protected $updated_at; - - /** @var string $deleted_at */ - protected $deleted_at; - - /** @var string $published_at */ - protected $published_at; - - /** - * HungNG_Custom_Based_model constructor. - * - * @author : 713uk13m - * @copyright: 713uk13m - */ - public function __construct() - { - parent::__construct(); - - log_message('info', 'HungNG_Custom_Based_model Class Initialized'); - - $this->db = $this->load->database('default', true, true); - $this->tableName = ''; - $this->primary_key = 'id'; - $this->created_at = 'created_at'; - $this->updated_at = 'updated_at'; - $this->deleted_at = 'deleted_at'; - $this->published_at = 'published_at'; - $this->is_not = ' !='; - $this->or_higher = ' >='; - $this->is_higher = ' >'; - $this->or_smaller = ' <='; - $this->is_smaller = ' <'; - $this->start_time = ' 00:00:00'; - $this->end_time = ' 23:59:59'; - } - - /** - * __destruct models - */ - public function __destruct() - { - if ($this->db->conn_id) { - $this->db->close(); - log_message( - 'info', - 'Model "HungNG_Custom_Based_model" destructed and database disconnected successfully!' - ); - } - } - - /** - * Function setDb - * - * @param string $db_group - * - * @return $this - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 12/09/2020 38:49 - */ - public function setDb($db_group = '') - { - $this->db = $this->load->database($db_group, true, true); - - return $this; - } - - /** - * Function setTableName - * - * @param string $tableName - * - * @return $this - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 30:49 - */ - public function setTableName($tableName = '') - { - $this->tableName = $tableName; - - return $this; - } - - /** - * Function getTableName - * - * @return string - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 30:45 - */ - public function getTableName() - { - return $this->tableName; - } - - /** - * Function bindDBPrefix - * - * @param $table - * - * @return string - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 27/03/2023 53:42 - */ - public function bindDBPrefix($table) - { - if (!empty($this->db->dbprefix)) { - if (strpos($table, $this->db->dbprefix)) { - return $table; - } - } - - return $this->db->dbprefix($table); - } - - /** - * Function close - * - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/25/2021 52:39 - */ - public function close() - { - $this->db->close(); - log_message( - 'info', - 'Class "HungNG_Custom_Based_model" database closed' - ); - } - - // ---------------------------------------------------------------------------------------------------------------------------------------- // - - /** - * Function get_off_set - * - * @param $size - * @param $page - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 22/03/2023 13:24 - */ - public function get_off_set($size = 500, $page = 0) - { - $size = (int)$size; - $page = (int)$page; - if ($page !== 0) { - if ($page <= 0 || empty($page)) { - $page = 1; - } - $start = ($page - 1) * $size; - } else { - $start = $page; - } - - return (int)$start; - } - - /** - * Function page_limit - * - * @param int $size - * @param int $page - * - * @return \CI_DB_query_builder - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 03/06/2022 20:38 - */ - public function page_limit($size = 500, $page = 0) - { - if ($size !== 'no_limit') { - $start = $this->get_off_set($size, $page); - - return $this->db->limit($size, $start); - } - - return $this->db; - } - - /** - * Function _page_limit alias of page_limit - * - * @param int $size - * @param int $page - * - * @return \CI_DB_query_builder - * @deprecated use page_limit method - * @author : 713uk13m - * @copyright : 713uk13m - * @time : 08/16/2021 30:54 - */ - public function _page_limit($size = 500, $page = 0) - { - return $this->page_limit($size, $page); - } - - /** - * Function bind_order_result - * - * Lưu ý: mặc định sẽ order theo giá trị $direction và $field, $field truyền vào - * Trong trường hợp sử dụng $table=order_by_field, cần setup cả table và field trong biến $order_by_field trước khi truyền vào để order cho đúng - * - * @param $order_by_field - * @param $direction - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 11/02/2023 49:18 - */ - public function bind_order_result($order_by_field, $direction = 'desc', $field = 'id', $table = '') - { - return $this->build_order_result($order_by_field, $direction, $field, $table); - } - - /** - * Function build_order_result - * - * Lưu ý: mặc định sẽ order theo giá trị $direction và $field, $field truyền vào - * Trong trường hợp sử dụng $table=order_by_field, cần setup cả table và field trong biến $order_by_field trước khi truyền vào để order cho đúng - * - * @param $order_by_field - * @param $direction - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 28:15 - */ - public function build_order_result($order_by_field, $direction = 'desc', $field = 'id', $table = '') - { - if (!empty($table)) { - $tableName = $this->bindDBPrefix(trim($table)) . '.'; - } else { - $tableName = $this->bindDBPrefix($this->tableName) . '.'; - } - if ($table === 'order_by_field') { - $tableName = ''; - } - if (isset($order_by_field) && is_array($order_by_field) && count($order_by_field) > 0) { - foreach ($order_by_field as $f) { - $this->db->order_by($tableName . $f['field_name'], $f['order_value']); - } - } else { - $direction = strtoupper(trim($direction)); - if ($direction === 'RANDOM') { - $this->db->order_by($tableName . $field, 'RANDOM'); - } else { - $this->db->order_by($tableName . $field, $direction); - } - } - - return $this->db; - } - - /** - * Function build_list_id_with_parent_id - Tạo 1 list các ID, trong đó chứa các tập con phụ thuộc của ID đ - * - * @param array|object|mixed $allSubId - * @param string|int $parentId - * - * @return array|string|int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 13:31 - */ - public function build_list_id_with_parent_id($allSubId, $parentId) - { - if (is_array($allSubId) || is_object($allSubId)) { - // Xác định lấy toàn bộ tin tức ở các category con - $countSub = count($allSubId); // Đếm bảng ghi Category con - if ($countSub) { - // Nếu tồn tại các category con - $listSub = array(); - $listSub[] = $parentId; // Push category cha - foreach ($allSubId as $item) { - $itemId = is_array($item) ? $item['id'] : $item->id; - $listSub[] = $itemId; // Push các category con vào mảng dữ liệu - } - - return $listSub; - } - } - - return $parentId; - } - - /** - * Function prepare_simple_wheres_not_statement - * - * @param $value - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 31:03 - */ - public function prepare_simple_wheres_not_statement($value, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - if ($value !== null) { - if (is_array($value)) { - $this->db->where_not_in($tableName . '.' . $field, $value); - } else { - $this->db->where($tableName . '.' . $field . $this->is_not, $value); - } - } - - return $this->db; - } - - /** - * Function prepare_simple_wheres_statement - * - * @param $value - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 31:11 - */ - public function prepare_simple_wheres_statement($value, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - if ($value !== null) { - if (is_array($value)) { - $this->db->where_in($tableName . '.' . $field, $value); - } else { - $this->db->where($tableName . '.' . $field, $value); - } - } - - return $this->db; - } - - /** - * Function prepare_wheres_statement - * - * @param $wheres - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 50:08 - */ - public function prepare_wheres_statement($wheres) - { - if (!empty($wheres) && is_array($wheres) && count($wheres) > 0) { - foreach ($wheres as $field => $value) { - if (is_array($value)) { - if (isset($value['field'], $value['value'])) { - if (is_array($value['value'])) { - $this->db->where_in($value['field'], $value['value']); - } else { - $this->db->where($value['field'] . ' ' . trim($value['operator']), $value['value']); - } - } else { - $this->db->where_in($field, $value); - } - } else { - $this->db->where($field, $value); - } - } - } - - return $this->db; - } - - /** - * Function prepare_wheres_not_statement - * - * @param $wheres - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 50:13 - */ - public function prepare_wheres_not_statement($wheres) - { - if (!empty($wheres) && is_array($wheres) && count($wheres) > 0) { - foreach ($wheres as $field => $value) { - if (is_array($value)) { - if (isset($value['field'], $value['value'])) { - if (is_array($value['value'])) { - $this->db->where_not_in($value['field'], $value['value']); - } else { - $this->db->where($value['field'] . ' ' . trim($value['operator']), $value['value']); - } - } else { - $this->db->where_not_in($field, $value); - } - } else { - $this->db->where($field . $this->is_not, $value); - } - } - } - - return $this->db; - } - - /** - * Function only_status_is_active - * - * @param $act - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @throws \HungNG_CI_Exception - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 27/03/2023 15:20 - */ - public function only_status_is_active($act = true, $field = 'status', $table = '') - { - if ($act === true) { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix( - $this->tableName - ); - $useField = !empty($field) ? trim($field) : 'status'; - $tableExists = $this->db->table_exists($tableName); - if ($tableExists === false) { - throw new HungNG_CI_Exception('Table ' . $tableName . ' không tồn tại', 404); - } - $fieldExists = $this->db->field_exists($useField, $tableName); - if ($fieldExists === false) { - throw new HungNG_CI_Exception( - 'Field ' . $useField . ' không tìm thấy trong bảng ' . $tableName, 404 - ); - } - - return $this->db->where($tableName . '.' . $useField, self::DEFAULT_STATUS_IS_ACTIVE); - } - - return $this->db; - } - - /** - * Function only_status_is_de_active - * - * @param $act - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @throws \HungNG_CI_Exception - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 27/03/2023 17:52 - */ - public function only_status_is_de_active($act = true, $field = 'status', $table = '') - { - if ($act === true) { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix( - $this->tableName - ); - $useField = !empty($field) ? trim($field) : 'status'; - $tableExists = $this->db->table_exists($tableName); - if ($tableExists === false) { - throw new HungNG_CI_Exception('Table ' . $tableName . ' không tồn tại', 404); - } - $fieldExists = $this->db->field_exists($useField, $tableName); - if ($fieldExists === false) { - throw new HungNG_CI_Exception( - 'Field ' . $useField . ' không tìm thấy trong bảng ' . $tableName, 404 - ); - } - - return $this->db->where($tableName . '.' . $useField, self::DEFAULT_STATUS_IS_DE_ACTIVE); - } - - return $this->db; - } - - /** - * Function bind_recursive_from_category - * - * @param $allSubId - * @param $parentId - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 00:20 - */ - public function bind_recursive_from_category($allSubId, $parentId, $field = 'categoryId', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $listID = $this->build_list_id_with_parent_id($allSubId, $parentId); - if (is_array($listID)) { - $this->db->where_in($tableName . '.' . $field, $listID); - } else { - $this->db->where($tableName . '.' . $field, $listID); - } - - return $this->db; - } - - /** - * Function filter_by_primary_id - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 03:06 - */ - public function filter_by_primary_id($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - if ($id !== null) { - if (is_array($id)) { - $this->db->where_in($tableName . '.' . $field, $id); - } else { - $this->db->where($tableName . '.' . $field, $id); - } - } - - return $this->db; - } - - /** - * Function build_operator_equal_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 03:02 - */ - public function build_operator_equal_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - if ($id !== null) { - if (is_array($id)) { - $this->db->where_in($tableName . '.' . $field, $id); - } else { - $this->db->where($tableName . '.' . $field, $id); - } - } - - return $this->db; - } - - /** - * Function build_operator_not_equal_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 02:59 - */ - public function build_operator_not_equal_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - if ($id !== null) { - if (is_array($id)) { - $this->db->where_not_in($tableName . '.' . $field, $id); - } else { - $this->db->where($tableName . '.' . $field . $this->is_not, $id); - } - } - - return $this->db; - } - - /** - * Function build_operator_less_than_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 02:56 - */ - public function build_operator_less_than_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_LESS_THAN, $id); - - return $this->db; - } - - /** - * Function build_operator_greater_than_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 02:53 - */ - public function build_operator_greater_than_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_GREATER_THAN, $id); - - return $this->db; - } - - /** - * Function build_operator_less_than_or_equal_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 02:50 - */ - public function build_operator_less_than_or_equal_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_LESS_THAN_OR_EQUAL_TO, $id); - - return $this->db; - } - - /** - * Function build_operator_greater_than_or_equal_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 02:46 - */ - public function build_operator_greater_than_or_equal_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $id); - - return $this->db; - } - - /** - * Function build_operator_space_ship_to - * - * @param $id - * @param $field - * @param $table - * - * @return bool|\CI_DB_query_builder|object - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 02:41 - */ - public function build_operator_space_ship_to($id, $field = 'id', $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_IS_SPACESHIP, $id); - - return $this->db; - } - - // ------------------------------------------ Database Metadata ------------------------------------------ // - - /** - * Function list_tables - * - * @return array|false|string - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 21:09 - */ - public function list_tables() - { - return $this->db->list_tables(); - } - - /** - * Function table_exists - * - * @param $table - * - * @return bool - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 25:08 - */ - public function table_exists($table) - { - return $this->db->table_exists($table); - } - - /** - * Function list_fields_on_table - * - * @param $table - * - * @return array|false|string - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 25:23 - */ - public function list_fields_on_table($table) - { - return $this->db->list_fields($table); - } - - /** - * Function field_exists_on_table - * - * @param $field - * @param $table - * - * @return bool - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 26:47 - */ - public function field_exists_on_table($field, $table) - { - return $this->db->field_exists($field, $table); - } - - /** - * Function list_all_field_data - * - * @param $table - * - * @return array|false - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 26:44 - */ - public function list_all_field_data($table) - { - return $this->db->field_data($table); - } - - // ---------------------------------------------------------------------------------------------------------------------------------------- // - - /** - * Function check_exists - * - * @param string $value - * @param mixed $field - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 30:20 - */ - public function check_exists($value = '', $field = null) - { - $this->db->select($this->primary_key); - $this->db->from($this->tableName); - if ($field === null) { - $this->db->where($this->primary_key, $value); - } else { - $this->db->where($field, $value); - } - - return $this->db->count_all_results(); - } - - /** - * Function get_last_id - * - * @param string $field - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 30:12 - */ - public function get_last_id($field = 'id') - { - $this->db->select($field); - $this->db->from($this->tableName); - $this->db->limit(1); - $this->db->order_by($field, 'DESC'); - $row = $this->db->get()->row(); - if (is_object($row)) { - return $row->$field; - } - - return 0; - } - - /** - * Function get_first_id - * - * @param $field - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 08:37 - */ - public function get_first_id($field = 'id') - { - $this->db->select($field); - $this->db->from($this->tableName); - $this->db->limit(1); - $this->db->order_by($field, 'ASC'); - $row = $this->db->get()->row(); - if (is_object($row)) { - return $row->$field; - } - - return 0; - } - - /** - * Function get_random_id - * - * @param $field - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/02/2023 08:41 - */ - public function get_random_id($field = 'id') - { - $this->db->select($field); - $this->db->from($this->tableName); - $this->db->limit(1); - $this->db->order_by($field, 'RANDOM'); - $row = $this->db->get()->row(); - if (is_object($row)) { - return $row->$field; - } - - return 0; - } - - /** - * Function get_all - * - * @param string $field - * - * @return array|array[]|object|object[] - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 30:08 - */ - public function get_all($field = '*') - { - $this->db->select($field); - $this->db->from($this->tableName); - - return $this->db->get()->result(); - } - - /** - * Function get_all_asc - * - * @param $field - * - * @return array|array[]|object|object[] - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 19:08 - */ - public function get_all_asc($field = '*') - { - $this->db->select($field); - $this->db->from($this->tableName); - $this->db->order_by($field, 'ASC'); - - return $this->db->get()->result(); - } - - /** - * Function get_all_desc - * - * @param $field - * - * @return array|array[]|object|object[] - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 16/02/2023 19:03 - */ - public function get_all_desc($field = '*') - { - $this->db->select($field); - $this->db->from($this->tableName); - $this->db->order_by($field, 'DESC'); - - return $this->db->get()->result(); - } - - /** - * Function count_all - * - * @param string $field - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 30:00 - */ - public function count_all($field = '*') - { - $this->db->select($field); - $this->db->from($this->tableName); - - return $this->db->count_all_results(); - } - - /** - * Function count_all_from_table - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 09/13/2021 07:51 - */ - public function count_all_from_table() - { - return $this->db->count_all($this->tableName); - } - - /** - * Function count_all_by_wheres - * - * @param $wheres - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 27/03/2023 04:52 - */ - public function count_all_by_wheres($wheres) - { - return $this->prepare_wheres_statement($wheres)->count_all_results($this->tableName); - } - - /** - * Function count_all_by_not_wheres - * - * @param $wheres - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 27/03/2023 05:47 - */ - public function count_all_by_not_wheres($wheres) - { - return $this->prepare_wheres_not_statement($wheres)->count_all_results($this->tableName); - } - - /** - * Function get_list_distinct - * - * @param string $field - * - * @return array|array[]|object|object[] - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:58 - */ - public function get_list_distinct($field = '*') - { - $this->db->distinct(); - $this->db->select($field); - $this->db->from($this->tableName); - - return $this->db->get()->result(); - } - - /** - * Function get_data_simple_result - * - * @param string $select - * @param array $wheres - * @param int $size - * @param int $page - * @param string[] $orderBy - * - * @return array|array[]|object|object[] - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 09/13/2021 16:49 - */ - public function get_data_simple_result( - $select = '*', - $wheres = array(), - $size = 75, - $page = 0, - $orderBy = array('id' => 'DESC') - ) { - $tableName = $this->bindDBPrefix($this->tableName); - $this->db->select($select); - $this->db->from($this->tableName); - if (count($wheres) > 0) { - foreach ($wheres as $field => $value) { - if (is_array($value)) { - $this->db->where_in($tableName . '.' . $field, $value); - } else { - $this->db->where($tableName . '.' . $field, $value); - } - } - } - - foreach ($orderBy as $orderField => $orderDirection) { - $this->db->order_by($tableName . '.' . $orderField, $orderDirection); - } - - $this->page_limit($size, $page); - - return $this->db->get()->result(); - } - - /** - * Function get_all_data_simple_result - * - * @param mixed $options - * - * @return array|array[]|object|object[] - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 25/11/2021 46:10 - */ - public function get_all_data_simple_result($options = null) - { - $this->db->from($this->tableName); - if (is_array($options)) { - foreach ($options as $field => $value) { - if (is_array($value)) { - $this->db->where_in($field, $value); - } else { - $this->db->where($field, $value); - } - } - } - - return $this->db->get()->result(); - } - - /** - * Function get_info - * - * @param string $value - * @param mixed $field - * @param bool $array - * - * @return array|mixed|object|null - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:55 - */ - public function get_info($value = '', $field = null, $array = false) - { - $this->db->from($this->tableName); - if ($field === null) { - $this->db->where($this->primary_key, $value); - } else { - $this->db->where($field, $value); - } - if ($array === true) { - return $this->db->get()->row_array(); - } - - return $this->db->get()->row(); - } - - /** - * Function get_value - * - * @param string $value_input - * @param mixed $field_input - * @param mixed $field_output - * - * @return array|mixed|object|null - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:51 - */ - public function get_value($value_input = '', $field_input = null, $field_output = null) - { - if (null !== $field_output) { - $this->db->select($field_output); - } - $this->db->from($this->tableName); - if ($field_input === null) { - $this->db->where($this->primary_key, $value_input); - } else { - $this->db->where($field_input, $value_input); - } - $query = $this->db->get(); - if (null !== $field_output) { - if (null === $query->row()) { - return null; - } - - return $query->row()->$field_output; - } - - return $query->row(); - } - - /** - * Function add - * - * @param array $data - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:47 - */ - public function add($data = array()) - { - $this->db->insert($this->tableName, $data); - - return $this->db->insert_id(); - } - - /** - * Function insert_batch - * - * @param array $data - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:44 - */ - public function insert_batch($data = array()) - { - $this->db->insert_batch($this->tableName, $data); - - return $this->db->insert_id(); - } - - /** - * Function update - * - * @param string $id - * @param array $data - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:32 - */ - public function update($id = '', $data = array()) - { - if (empty($id)) { - log_message('error', 'Update method give Input Primary Key is Empty'); - - return 0; - } - $this->db->where($this->primary_key, $id); - $this->db->update($this->tableName, $data); - - return $this->db->affected_rows(); - } - - /** - * Function where_update - * - * @param $wheres - * @param $data - * @param $table - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 22/03/2023 32:40 - */ - public function where_update($wheres, $data, $table = '') - { - if (empty($wheres)) { - log_message('error', 'Update method give Input Wheres is Empty'); - - return 0; - } - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->prepare_wheres_statement($wheres); - $this->db->update($tableName, $data); - - return $this->db->affected_rows(); - } - - /** - * Function delete - * - * @param string $id - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 09/20/2021 38:36 - */ - public function delete($id = '') - { - if (empty($id)) { - log_message('error', 'Delete method give Input Primary Key is Empty'); - - return 0; - } - $this->db->where($this->primary_key, $id); - $this->db->delete($this->tableName); - - return $this->db->affected_rows(); - } - - /** - * Function where_delete - * - * @param $wheres - * @param $data - * @param $table - * - * @return int - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 22/03/2023 33:27 - */ - public function where_delete($wheres, $data, $table = '') - { - if (empty($wheres)) { - log_message('error', 'Delete method give Input Wheres is Empty'); - - return 0; - } - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - $this->prepare_wheres_statement($wheres); - $this->db->delete($tableName, $data); - - return $this->db->affected_rows(); - } - - /** - * Function request_builder - * - * @param $search - * @param $table - * - * @author : 713uk13m - * @copyright: 713uk13m - * @time : 08/16/2021 29:37 - */ - public function request_builder($search, $table = '') - { - $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); - if (!empty($search)) { - foreach ($search as $field => $value) { - if (!empty($value) && $this->db->field_exists($field, $tableName)) { - if (is_array($value)) { - $this->db->where_in($tableName . '.' . $field, $value); - } else { - $this->db->like($tableName . '.' . $field, $value); - } - } - if ($field === 'sort') { - $sort = strpos($value, '-') === false ? 'DESC' : 'ASC'; - $column = (strpos($value, '-') === false) ? $value : substr($value, 1); - if ($this->db->field_exists($column, $tableName)) { - $this->db->order_by($tableName . '.' . $column, $sort); - } - } - } - } - } - } + /** + * Class HungNA_Based_model + * + * @author 713uk13m + * @copyright 713uk13m + * + * @property CI_Benchmark $benchmark This class enables you to mark points and calculate the time difference between them. Memory consumption can also be displayed. + * @property CI_Calendar $calendar This class enables the creation of calendars + * @property CI_Cache $cache Caching Class + * @property CI_Cart $cart Shopping Cart Class + * @property CI_Config $config This class contains functions that enable config files to be managed + * @property CI_Controller $controller This class object is the super class that every library in CodeIgniter will be assigned to + * @property CI_DB_forge $dbforge Database Forge Class + * @property CI_DB_pdo_driver|CI_DB_query_builder|CI_DB_driver $db This is the platform-independent base Query Builder implementation class + * @property CI_DB_utility $dbutil Database Utility Class + * @property CI_Driver_Library $driver Driver Library Class + * @property CI_Email $email Permits email to be sent using Mail, Sendmail, or SMTP + * @property CI_Encrypt $encrypt Provides two-way keyed encoding using Mcrypt + * @property CI_Encryption $encryption Provides two-way keyed encryption via PHP's MCrypt and/or OpenSSL extensions + * @property CI_Exceptions $exceptions Exceptions Class + * @property CI_Form_validation $form_validation Form Validation Class + * @property CI_FTP $ftp FTP Class + * @property CI_Hooks $hooks Provides a mechanism to extend the base system without hacking + * @property CI_Image_lib $image_lib Image Manipulation class + * @property CI_Input $input Pre-processes global input data for security + * @property CI_Javascript $javascript Javascript Class + * @property CI_Jquery $jquery Jquery Class + * @property CI_Lang $lang Language Class + * @property CI_Loader $load Loads framework components + * @property CI_Log $log Logging Class + * @property CI_Migration $migration All migrations should implement this, forces up() and down() and gives access to the CI super-global + * @property CI_Model $model CodeIgniter Model Class + * @property CI_Output $output Responsible for sending final output to the browser + * @property CI_Pagination $pagination Pagination Class + * @property CI_Parser $parser Parser Class + * @property CI_Profiler $profiler This class enables you to display benchmark, query, and other data in order to help with debugging and optimization. + * @property CI_Router $router Parses URIs and determines routing + * @property CI_Security $security Security Class + * @property CI_Session $session Session Class + * @property CI_Table $table Lets you create tables manually or from database result objects, or arrays + * @property CI_Trackback $trackback Trackback Sending/Receiving Class + * @property CI_Typography $typography Typography Class + * @property CI_Unit_test $unit Simple testing class + * @property CI_Upload $upload File Uploading Class + * @property CI_URI $uri Parses URIs and determines routing + * @property CI_User_agent $agent Identifies the platform, browser, robot, or mobile device of the browsing agent + * @property CI_Xmlrpc $xmlrpc XML-RPC request handler class + * @property CI_Xmlrpcs $xmlrpcs XML-RPC server class + * @property CI_Zip $zip Zip Compression Class + * @property CI_Utf8 $utf8 Provides support for UTF-8 environments + */ + class HungNG_Custom_Based_model extends CI_Model + { + const OPERATOR_EQUAL_TO = '='; + const OPERATOR_NOT_EQUAL_TO = '!='; + const OPERATOR_LESS_THAN = '<'; + const OPERATOR_LESS_THAN_OR_EQUAL_TO = '<='; + const OPERATOR_GREATER_THAN = '>'; + const OPERATOR_GREATER_THAN_OR_EQUAL_TO = '>='; + const OPERATOR_IS_SPACESHIP = '<=>'; + const OPERATOR_IS_IN = 'IN'; + const OPERATOR_IS_LIKE = 'LIKE'; + const OPERATOR_IS_LIKE_BINARY = 'LIKE BINARY'; + const OPERATOR_IS_ILIKE = 'ilike'; + const OPERATOR_IS_NOT_LIKE = 'NOT LIKE'; + const OPERATOR_IS_NULL = 'IS NULL'; + const OPERATOR_IS_NOT_NULL = 'IS NOT NULL'; + const ORDER_ASCENDING = 'ASC'; + const ORDER_DESCENDING = 'DESC'; + const ORDER_RANDOM = 'RAND'; + const DEFAULT_STATUS_IS_ACTIVE = 1; + const DEFAULT_STATUS_IS_DE_ACTIVE = 0; + + /** @var \CI_DB_query_builder $db */ + protected $db; + + /** @var string $tableName */ + protected $tableName; + + /** @var string $primary_key */ + protected $primary_key; + + /** @var string $is_not $is_not */ + protected $is_not; + + /** @var string $or_higher */ + protected $or_higher; + + /** @var string $is_higher */ + protected $is_higher; + + /** @var string $or_smaller */ + protected $or_smaller; + + /** @var string $is_smaller */ + protected $is_smaller; + + /** @var array $field */ + protected $field = array(); + + /** @var string $start_time */ + protected $start_time; + + /** @var string $end_time */ + protected $end_time; + + /** @var string $created_at */ + protected $created_at; + + /** @var string $updated_at */ + protected $updated_at; + + /** @var string $deleted_at */ + protected $deleted_at; + + /** @var string $published_at */ + protected $published_at; + + /** + * HungNG_Custom_Based_model constructor. + * + * @author : 713uk13m + * @copyright: 713uk13m + */ + public function __construct() + { + parent::__construct(); + + log_message('info', 'HungNG_Custom_Based_model Class Initialized'); + + $this->db = $this->load->database('default', true, true); + $this->tableName = ''; + $this->primary_key = 'id'; + $this->created_at = 'created_at'; + $this->updated_at = 'updated_at'; + $this->deleted_at = 'deleted_at'; + $this->published_at = 'published_at'; + $this->is_not = ' !='; + $this->or_higher = ' >='; + $this->is_higher = ' >'; + $this->or_smaller = ' <='; + $this->is_smaller = ' <'; + $this->start_time = ' 00:00:00'; + $this->end_time = ' 23:59:59'; + } + + /** + * __destruct models + */ + public function __destruct() + { + if ($this->db->conn_id) { + $this->db->close(); + log_message( + 'info', + 'Model "HungNG_Custom_Based_model" destructed and database disconnected successfully!' + ); + } + } + + /** + * Function setDb + * + * @param string $db_group + * + * @return $this + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 12/09/2020 38:49 + */ + public function setDb($db_group = '') + { + $this->db = $this->load->database($db_group, true, true); + + return $this; + } + + /** + * Function setTableName + * + * @param string $tableName + * + * @return $this + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 30:49 + */ + public function setTableName($tableName = '') + { + $this->tableName = $tableName; + + return $this; + } + + /** + * Function getTableName + * + * @return string + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 30:45 + */ + public function getTableName() + { + return $this->tableName; + } + + /** + * Function bindDBPrefix + * + * @param $table + * + * @return string + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 27/03/2023 53:42 + */ + public function bindDBPrefix($table) + { + if (!empty($this->db->dbprefix)) { + if (strpos($table, $this->db->dbprefix)) { + return $table; + } + } + + return $this->db->dbprefix($table); + } + + /** + * Function close + * + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/25/2021 52:39 + */ + public function close() + { + if ($this->db->conn_id) { + $this->db->close(); + log_message( + 'info', + 'Model "HungNG_Custom_Based_model" database disconnected successfully!' + ); + } + } + + // ---------------------------------------------------------------------------------------------------------------------------------------- // + + /** + * Function get_off_set + * + * @param $size + * @param $page + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 22/03/2023 13:24 + */ + public function get_off_set($size = 500, $page = 0) + { + $size = (int)$size; + $page = (int)$page; + if ($page !== 0) { + if ($page <= 0 || empty($page)) { + $page = 1; + } + $start = ($page - 1) * $size; + } else { + $start = $page; + } + + return (int)$start; + } + + /** + * Function page_limit + * + * @param int $size + * @param int $page + * + * @return \CI_DB_query_builder + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 03/06/2022 20:38 + */ + public function page_limit($size = 500, $page = 0) + { + if ($size !== 'no_limit') { + $start = $this->get_off_set($size, $page); + return $this->db->limit($size, $start); + } + return $this->db; + } + + /** + * Function _page_limit alias of page_limit + * + * @param int $size + * @param int $page + * + * @return \CI_DB_query_builder + * @deprecated use page_limit method + * @author : 713uk13m + * @copyright : 713uk13m + * @time : 08/16/2021 30:54 + */ + public function _page_limit($size = 500, $page = 0) + { + return $this->page_limit($size, $page); + } + + /** + * Function bind_order_result + * + * Lưu ý: mặc định sẽ order theo giá trị $direction và $field, $field truyền vào + * Trong trường hợp sử dụng $table=order_by_field, cần setup cả table và field trong biến $order_by_field trước khi truyền vào để order cho đúng + * + * @param $order_by_field + * @param $direction + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 11/02/2023 49:18 + */ + public function bind_order_result($order_by_field, $direction = 'desc', $field = 'id', $table = '') + { + return $this->build_order_result($order_by_field, $direction, $field, $table); + } + + /** + * Function build_order_result + * + * Lưu ý: mặc định sẽ order theo giá trị $direction và $field, $field truyền vào + * Trong trường hợp sử dụng $table=order_by_field, cần setup cả table và field trong biến $order_by_field trước khi truyền vào để order cho đúng + * + * @param $order_by_field + * @param $direction + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 28:15 + */ + public function build_order_result($order_by_field, $direction = 'desc', $field = 'id', $table = '') + { + if (!empty($table)) { + $tableName = $this->bindDBPrefix(trim($table)) . '.'; + } else { + $tableName = $this->bindDBPrefix($this->tableName) . '.'; + } + if ($table === 'order_by_field') { + $tableName = ''; + } + if (isset($order_by_field) && is_array($order_by_field) && count($order_by_field) > 0) { + foreach ($order_by_field as $f) { + $this->db->order_by($tableName . $f['field_name'], $f['order_value']); + } + } else { + $direction = strtoupper(trim($direction)); + if ($direction === 'RANDOM') { + $this->db->order_by($tableName . $field, 'RANDOM'); + } else { + $this->db->order_by($tableName . $field, $direction); + } + } + + return $this->db; + } + + /** + * Function build_list_id_with_parent_id - Tạo 1 list các ID, trong đó chứa các tập con phụ thuộc của ID đ + * + * @param array|object|mixed $allSubId + * @param string|int $parentId + * + * @return array|string|int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 13:31 + */ + public function build_list_id_with_parent_id($allSubId, $parentId) + { + if (is_array($allSubId) || is_object($allSubId)) { + // Xác định lấy toàn bộ tin tức ở các category con + $countSub = count($allSubId); // Đếm bảng ghi Category con + if ($countSub) { + // Nếu tồn tại các category con + $listSub = array(); + $listSub[] = $parentId; // Push category cha + foreach ($allSubId as $item) { + $itemId = is_array($item) ? $item['id'] : $item->id; + $listSub[] = $itemId; // Push các category con vào mảng dữ liệu + } + + return $listSub; + } + } + + return $parentId; + } + + /** + * Function prepare_simple_wheres_not_statement + * + * @param $value + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 31:03 + */ + public function prepare_simple_wheres_not_statement($value, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + if ($value !== null) { + if (is_array($value)) { + $this->db->where_not_in($tableName . '.' . $field, $value); + } else { + $this->db->where($tableName . '.' . $field . $this->is_not, $value); + } + } + + return $this->db; + } + + /** + * Function prepare_simple_wheres_statement + * + * @param $value + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 31:11 + */ + public function prepare_simple_wheres_statement($value, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + if ($value !== null) { + if (is_array($value)) { + $this->db->where_in($tableName . '.' . $field, $value); + } else { + $this->db->where($tableName . '.' . $field, $value); + } + } + + return $this->db; + } + + /** + * Function prepare_wheres_statement + * + * @param $wheres + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 50:08 + */ + public function prepare_wheres_statement($wheres) + { + if (!empty($wheres) && is_array($wheres) && count($wheres) > 0) { + foreach ($wheres as $field => $value) { + if (is_array($value)) { + if (isset($value['field'], $value['value'])) { + if (is_array($value['value'])) { + $this->db->where_in($value['field'], $value['value']); + } else { + $this->db->where($value['field'] . ' ' . trim($value['operator']), $value['value']); + } + } else { + $this->db->where_in($field, $value); + } + } else { + $this->db->where($field, $value); + } + } + } + + return $this->db; + } + + /** + * Function prepare_wheres_not_statement + * + * @param $wheres + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 50:13 + */ + public function prepare_wheres_not_statement($wheres) + { + if (!empty($wheres) && is_array($wheres) && count($wheres) > 0) { + foreach ($wheres as $field => $value) { + if (is_array($value)) { + if (isset($value['field'], $value['value'])) { + if (is_array($value['value'])) { + $this->db->where_not_in($value['field'], $value['value']); + } else { + $this->db->where($value['field'] . ' ' . trim($value['operator']), $value['value']); + } + } else { + $this->db->where_not_in($field, $value); + } + } else { + $this->db->where($field . $this->is_not, $value); + } + } + } + + return $this->db; + } + + /** + * Function only_status_is_active + * + * @param $act + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @throws \HungNG_CI_Exception + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 27/03/2023 15:20 + */ + public function only_status_is_active($act = true, $field = 'status', $table = '') + { + if ($act === true) { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix( + $this->tableName + ); + $useField = !empty($field) ? trim($field) : 'status'; + $tableExists = $this->db->table_exists($tableName); + if ($tableExists === false) { + throw new HungNG_CI_Exception('Table ' . $tableName . ' không tồn tại', 404); + } + $fieldExists = $this->db->field_exists($useField, $tableName); + if ($fieldExists === false) { + throw new HungNG_CI_Exception( + 'Field ' . $useField . ' không tìm thấy trong bảng ' . $tableName, 404 + ); + } + + return $this->db->where($tableName . '.' . $useField, self::DEFAULT_STATUS_IS_ACTIVE); + } + + return $this->db; + } + + /** + * Function only_status_is_de_active + * + * @param $act + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @throws \HungNG_CI_Exception + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 27/03/2023 17:52 + */ + public function only_status_is_de_active($act = true, $field = 'status', $table = '') + { + if ($act === true) { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix( + $this->tableName + ); + $useField = !empty($field) ? trim($field) : 'status'; + $tableExists = $this->db->table_exists($tableName); + if ($tableExists === false) { + throw new HungNG_CI_Exception('Table ' . $tableName . ' không tồn tại', 404); + } + $fieldExists = $this->db->field_exists($useField, $tableName); + if ($fieldExists === false) { + throw new HungNG_CI_Exception( + 'Field ' . $useField . ' không tìm thấy trong bảng ' . $tableName, 404 + ); + } + + return $this->db->where($tableName . '.' . $useField, self::DEFAULT_STATUS_IS_DE_ACTIVE); + } + + return $this->db; + } + + /** + * Function bind_recursive_from_category + * + * @param $allSubId + * @param $parentId + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 00:20 + */ + public function bind_recursive_from_category($allSubId, $parentId, $field = 'categoryId', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $listID = $this->build_list_id_with_parent_id($allSubId, $parentId); + if (is_array($listID)) { + $this->db->where_in($tableName . '.' . $field, $listID); + } else { + $this->db->where($tableName . '.' . $field, $listID); + } + + return $this->db; + } + + /** + * Function filter_by_primary_id + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 03:06 + */ + public function filter_by_primary_id($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + if ($id !== null) { + if (is_array($id)) { + $this->db->where_in($tableName . '.' . $field, $id); + } else { + $this->db->where($tableName . '.' . $field, $id); + } + } + + return $this->db; + } + + /** + * Function build_operator_equal_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 03:02 + */ + public function build_operator_equal_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + if ($id !== null) { + if (is_array($id)) { + $this->db->where_in($tableName . '.' . $field, $id); + } else { + $this->db->where($tableName . '.' . $field, $id); + } + } + + return $this->db; + } + + /** + * Function build_operator_not_equal_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 02:59 + */ + public function build_operator_not_equal_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + if ($id !== null) { + if (is_array($id)) { + $this->db->where_not_in($tableName . '.' . $field, $id); + } else { + $this->db->where($tableName . '.' . $field . $this->is_not, $id); + } + } + + return $this->db; + } + + /** + * Function build_operator_less_than_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 02:56 + */ + public function build_operator_less_than_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_LESS_THAN, $id); + + return $this->db; + } + + /** + * Function build_operator_greater_than_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 02:53 + */ + public function build_operator_greater_than_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_GREATER_THAN, $id); + + return $this->db; + } + + /** + * Function build_operator_less_than_or_equal_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 02:50 + */ + public function build_operator_less_than_or_equal_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_LESS_THAN_OR_EQUAL_TO, $id); + + return $this->db; + } + + /** + * Function build_operator_greater_than_or_equal_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 02:46 + */ + public function build_operator_greater_than_or_equal_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $id); + + return $this->db; + } + + /** + * Function build_operator_space_ship_to + * + * @param $id + * @param $field + * @param $table + * + * @return bool|\CI_DB_query_builder|object + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 02:41 + */ + public function build_operator_space_ship_to($id, $field = 'id', $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->db->where($tableName . '.' . $field . ' ' . self::OPERATOR_IS_SPACESHIP, $id); + + return $this->db; + } + + // ------------------------------------------ Database Metadata ------------------------------------------ // + + /** + * Function list_tables + * + * @return array|false|string + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 21:09 + */ + public function list_tables() + { + return $this->db->list_tables(); + } + + /** + * Function table_exists + * + * @param $table + * + * @return bool + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 25:08 + */ + public function table_exists($table) + { + return $this->db->table_exists($table); + } + + /** + * Function list_fields_on_table + * + * @param $table + * + * @return array|false|string + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 25:23 + */ + public function list_fields_on_table($table) + { + return $this->db->list_fields($table); + } + + /** + * Function field_exists_on_table + * + * @param $field + * @param $table + * + * @return bool + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 26:47 + */ + public function field_exists_on_table($field, $table) + { + return $this->db->field_exists($field, $table); + } + + /** + * Function list_all_field_data + * + * @param $table + * + * @return array|false + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 26:44 + */ + public function list_all_field_data($table) + { + return $this->db->field_data($table); + } + + // ---------------------------------------------------------------------------------------------------------------------------------------- // + + /** + * Function check_exists + * + * @param string $value + * @param mixed $field + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 30:20 + */ + public function check_exists($value = '', $field = null) + { + $this->db->select($this->primary_key); + $this->db->from($this->tableName); + if ($field === null) { + $this->db->where($this->primary_key, $value); + } else { + $this->db->where($field, $value); + } + + return $this->db->count_all_results(); + } + + /** + * Function get_last_id + * + * @param string $field + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 30:12 + */ + public function get_last_id($field = 'id') + { + $this->db->select($field); + $this->db->from($this->tableName); + $this->db->limit(1); + $this->db->order_by($field, 'DESC'); + $row = $this->db->get()->row(); + if (is_object($row)) { + return $row->$field; + } + + return 0; + } + + /** + * Function get_first_id + * + * @param $field + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 08:37 + */ + public function get_first_id($field = 'id') + { + $this->db->select($field); + $this->db->from($this->tableName); + $this->db->limit(1); + $this->db->order_by($field, 'ASC'); + $row = $this->db->get()->row(); + if (is_object($row)) { + return $row->$field; + } + + return 0; + } + + /** + * Function get_random_id + * + * @param $field + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/02/2023 08:41 + */ + public function get_random_id($field = 'id') + { + $this->db->select($field); + $this->db->from($this->tableName); + $this->db->limit(1); + $this->db->order_by($field, 'RANDOM'); + $row = $this->db->get()->row(); + if (is_object($row)) { + return $row->$field; + } + + return 0; + } + + /** + * Function get_all + * + * @param string $field + * + * @return array|array[]|object|object[] + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 30:08 + */ + public function get_all($field = '*') + { + $this->db->select($field); + $this->db->from($this->tableName); + + return $this->db->get()->result(); + } + + /** + * Function get_all_asc + * + * @param $field + * + * @return array|array[]|object|object[] + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 19:08 + */ + public function get_all_asc($field = '*') + { + $this->db->select($field); + $this->db->from($this->tableName); + $this->db->order_by($field, 'ASC'); + + return $this->db->get()->result(); + } + + /** + * Function get_all_desc + * + * @param $field + * + * @return array|array[]|object|object[] + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 16/02/2023 19:03 + */ + public function get_all_desc($field = '*') + { + $this->db->select($field); + $this->db->from($this->tableName); + $this->db->order_by($field, 'DESC'); + + return $this->db->get()->result(); + } + + /** + * Function count_all + * + * @param string $field + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 30:00 + */ + public function count_all($field = '*') + { + $this->db->select($field); + $this->db->from($this->tableName); + + return $this->db->count_all_results(); + } + + /** + * Function count_all_from_table + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 09/13/2021 07:51 + */ + public function count_all_from_table() + { + return $this->db->count_all($this->tableName); + } + + /** + * Function count_all_by_wheres + * + * @param $wheres + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 27/03/2023 04:52 + */ + public function count_all_by_wheres($wheres) + { + return $this->prepare_wheres_statement($wheres)->count_all_results($this->tableName); + } + + /** + * Function count_all_by_not_wheres + * + * @param $wheres + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 27/03/2023 05:47 + */ + public function count_all_by_not_wheres($wheres) + { + return $this->prepare_wheres_not_statement($wheres)->count_all_results($this->tableName); + } + + /** + * Function get_list_distinct + * + * @param string $field + * + * @return array|array[]|object|object[] + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:58 + */ + public function get_list_distinct($field = '*') + { + $this->db->distinct(); + $this->db->select($field); + $this->db->from($this->tableName); + + return $this->db->get()->result(); + } + + /** + * Function get_data_simple_result + * + * @param string $select + * @param array $wheres + * @param int $size + * @param int $page + * @param string[] $orderBy + * + * @return array|array[]|object|object[] + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 09/13/2021 16:49 + */ + public function get_data_simple_result( + $select = '*', + $wheres = array(), + $size = 75, + $page = 0, + $orderBy = array('id' => 'DESC') + ) { + $tableName = $this->bindDBPrefix($this->tableName); + $this->db->select($select); + $this->db->from($this->tableName); + if (count($wheres) > 0) { + foreach ($wheres as $field => $value) { + if (is_array($value)) { + $this->db->where_in($tableName . '.' . $field, $value); + } else { + $this->db->where($tableName . '.' . $field, $value); + } + } + } + + foreach ($orderBy as $orderField => $orderDirection) { + $this->db->order_by($tableName . '.' . $orderField, $orderDirection); + } + + $this->page_limit($size, $page); + + return $this->db->get()->result(); + } + + /** + * Function get_all_data_simple_result + * + * @param mixed $options + * + * @return array|array[]|object|object[] + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 25/11/2021 46:10 + */ + public function get_all_data_simple_result($options = null) + { + $this->db->from($this->tableName); + if (is_array($options)) { + foreach ($options as $field => $value) { + if (is_array($value)) { + $this->db->where_in($field, $value); + } else { + $this->db->where($field, $value); + } + } + } + + return $this->db->get()->result(); + } + + /** + * Function get_info + * + * @param string $value + * @param mixed $field + * @param bool $array + * + * @return array|mixed|object|null + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:55 + */ + public function get_info($value = '', $field = null, $array = false) + { + $this->db->from($this->tableName); + if ($field === null) { + $this->db->where($this->primary_key, $value); + } else { + $this->db->where($field, $value); + } + if ($array === true) { + return $this->db->get()->row_array(); + } + + return $this->db->get()->row(); + } + + /** + * Function get_value + * + * @param string $value_input + * @param mixed $field_input + * @param mixed $field_output + * + * @return array|mixed|object|null + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:51 + */ + public function get_value($value_input = '', $field_input = null, $field_output = null) + { + if (null !== $field_output) { + $this->db->select($field_output); + } + $this->db->from($this->tableName); + if ($field_input === null) { + $this->db->where($this->primary_key, $value_input); + } else { + $this->db->where($field_input, $value_input); + } + $query = $this->db->get(); + if (null !== $field_output) { + if (null === $query->row()) { + return null; + } + + return $query->row()->$field_output; + } + + return $query->row(); + } + + /** + * Function add + * + * @param array $data + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:47 + */ + public function add($data = array()) + { + $this->db->insert($this->tableName, $data); + + return $this->db->insert_id(); + } + + /** + * Function insert_batch + * + * @param array $data + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:44 + */ + public function insert_batch($data = array()) + { + $this->db->insert_batch($this->tableName, $data); + + return $this->db->insert_id(); + } + + /** + * Function update + * + * @param string $id + * @param array $data + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:32 + */ + public function update($id = '', $data = array()) + { + if (empty($id)) { + log_message('error', 'Update method give Input Primary Key is Empty'); + + return 0; + } + $this->db->where($this->primary_key, $id); + $this->db->update($this->tableName, $data); + + return $this->db->affected_rows(); + } + + /** + * Function where_update + * + * @param $wheres + * @param $data + * @param $table + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 22/03/2023 32:40 + */ + public function where_update($wheres, $data, $table = '') + { + if (empty($wheres)) { + log_message('error', 'Update method give Input Wheres is Empty'); + + return 0; + } + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->prepare_wheres_statement($wheres); + $this->db->update($tableName, $data); + + return $this->db->affected_rows(); + } + + /** + * Function delete + * + * @param string $id + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 09/20/2021 38:36 + */ + public function delete($id = '') + { + if (empty($id)) { + log_message('error', 'Delete method give Input Primary Key is Empty'); + + return 0; + } + $this->db->where($this->primary_key, $id); + $this->db->delete($this->tableName); + + return $this->db->affected_rows(); + } + + /** + * Function where_delete + * + * @param $wheres + * @param $data + * @param $table + * + * @return int + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 22/03/2023 33:27 + */ + public function where_delete($wheres, $data, $table = '') + { + if (empty($wheres)) { + log_message('error', 'Delete method give Input Wheres is Empty'); + + return 0; + } + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + $this->prepare_wheres_statement($wheres); + $this->db->delete($tableName, $data); + + return $this->db->affected_rows(); + } + + /** + * Function request_builder + * + * @param $search + * @param $table + * + * @author : 713uk13m + * @copyright: 713uk13m + * @time : 08/16/2021 29:37 + */ + public function request_builder($search, $table = '') + { + $tableName = !empty($table) ? $this->bindDBPrefix(trim($table)) : $this->bindDBPrefix($this->tableName); + if (!empty($search)) { + foreach ($search as $field => $value) { + if (!empty($value) && $this->db->field_exists($field, $tableName)) { + if (is_array($value)) { + $this->db->where_in($tableName . '.' . $field, $value); + } else { + $this->db->like($tableName . '.' . $field, $value); + } + } + if ($field === 'sort') { + $sort = strpos($value, '-') === false ? 'DESC' : 'ASC'; + $column = (strpos($value, '-') === false) ? $value : substr($value, 1); + if ($this->db->field_exists($column, $tableName)) { + $this->db->order_by($tableName . '.' . $column, $sort); + } + } + } + } + } + } } diff --git a/system/core/Common.php b/system/core/Common.php index 1b9f96a..7081736 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -468,7 +468,7 @@ function show_error($message, $status_code = 500, $heading = 'An Error Was Encou { $exit_status = 1; // EXIT_ERROR } - + /** @var CI_Exceptions $_error */ $_error =& load_class('Exceptions', 'core'); echo $_error->show_error($heading, $message, 'error_general', $status_code); exit($exit_status); @@ -492,6 +492,7 @@ function show_error($message, $status_code = 500, $heading = 'An Error Was Encou */ function show_404($page = '', $log_error = TRUE) { + /** @var CI_Exceptions $_error */ $_error =& load_class('Exceptions', 'core'); $_error->show_404($page, $log_error); exit(4); // EXIT_UNKNOWN_FILE @@ -557,7 +558,7 @@ function set_status_header($code = 200, $text = '') if (empty($text)) { is_int($code) OR $code = (int) $code; - $stati = array( + $static = array( 100 => 'Continue', 101 => 'Switching Protocols', @@ -610,9 +611,9 @@ function set_status_header($code = 200, $text = '') 511 => 'Network Authentication Required', ); - if (isset($stati[$code])) + if (isset($static[$code])) { - $text = $stati[$code]; + $text = $static[$code]; } else { @@ -675,6 +676,7 @@ function _error_handler($severity, $message, $filepath, $line) return; } + /** @var CI_Exceptions $_error */ $_error =& load_class('Exceptions', 'core'); $_error->log_exception($severity, $message, $filepath, $line); @@ -710,6 +712,7 @@ function _error_handler($severity, $message, $filepath, $line) */ function _exception_handler($exception) { + /** @var CI_Exceptions $_error */ $_error =& load_class('Exceptions', 'core'); $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine()); @@ -825,6 +828,22 @@ function html_escape($var, $double_encode = TRUE) // ------------------------------------------------------------------------ +if ( ! function_exists('html_escape_all')){ + /** + * Escape all HTML, JavaScript, and CSS + * + * @param string $input The input string + * @param string $encoding Which character encoding are we using? + * @return string + */ + function html_escape_all($input, $encoding = 'UTF-8') + { + return htmlentities($input, ENT_QUOTES | ENT_HTML5, $encoding); + } +} + +// ------------------------------------------------------------------------ + if ( ! function_exists('_stringify_attributes')) { /** diff --git a/system/core/Controller.php b/system/core/Controller.php index 3713ae0..e1cdd4f 100644 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -1,4 +1,5 @@ $class) - { - $this->$var =& load_class($class); - } + // Assign all the class objects that were instantiated by the + // bootstrap file (CodeIgniter.php) to local class variables + // so that CI can run as one big super object. + foreach (is_loaded() as $var => $class) { + $this->$var =& load_class($class); + } - $this->load =& load_class('Loader', 'core'); - $this->load->initialize(); - log_message('info', 'Controller Class Initialized'); - } + $this->load =& load_class('Loader', 'core'); + $this->load->initialize(); + log_message('info', 'Controller Class Initialized'); + } - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- - /** - * Get the CI singleton - * - * @static - * @return object - */ - public static function &get_instance() - { - return self::$instance; - } + /** + * Get the CI singleton + * + * @static + * @return object + */ + public static function &get_instance() + { + return self::$instance; + } } diff --git a/system/core/Loader.php b/system/core/Loader.php index ee37294..6b03122 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -1,4 +1,5 @@ TRUE); - - /** - * List of paths to load libraries from - * - * @var array - */ - protected $_ci_library_paths = array(APPPATH, BASEPATH); - - /** - * List of paths to load models from - * - * @var array - */ - protected $_ci_model_paths = array(APPPATH); - - /** - * List of paths to load helpers from - * - * @var array - */ - protected $_ci_helper_paths = array(APPPATH, BASEPATH); - - /** - * List of cached variables - * - * @var array - */ - protected $_ci_cached_vars = array(); - - /** - * List of loaded classes - * - * @var array - */ - protected $_ci_classes = array(); - - /** - * List of loaded models - * - * @var array - */ - protected $_ci_models = array(); - - /** - * List of loaded helpers - * - * @var array - */ - protected $_ci_helpers = array(); - - /** - * List of class name mappings - * - * @var array - */ - protected $_ci_varmap = array( - 'unit_test' => 'unit', - 'user_agent' => 'agent' - ); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Sets component load paths, gets the initial output buffering level. - * - * @return void - */ - public function __construct() - { - $this->_ci_ob_level = ob_get_level(); - $this->_ci_classes =& is_loaded(); - - log_message('info', 'Loader Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initializer - * - * @todo Figure out a way to move this to the constructor - * without breaking *package_path*() methods. - * @uses CI_Loader::_ci_autoloader() - * @used-by CI_Controller::__construct() - * @return void - */ - public function initialize() - { - $this->_ci_autoloader(); - } - - // -------------------------------------------------------------------- - - /** - * Is Loaded - * - * A utility method to test if a class is in the self::$_ci_classes array. - * - * @used-by Mainly used by Form Helper function _get_validation_object(). - * - * @param string $class Class name to check for - * @return string|bool Class object name if loaded or FALSE - */ - public function is_loaded($class) - { - return array_search(ucfirst($class), $this->_ci_classes, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Library Loader - * - * Loads and instantiates libraries. - * Designed to be called from application controllers. - * - * @param mixed $library Library name - * @param array $params Optional parameters to pass to the library class constructor - * @param string $object_name An optional object name to assign to - * @return object - */ - public function library($library, $params = NULL, $object_name = NULL) - { - if (empty($library)) - { - return $this; - } - elseif (is_array($library)) - { - foreach ($library as $key => $value) - { - if (is_int($key)) - { - $this->library($value, $params); - } - else - { - $this->library($key, $params, $value); - } - } - - return $this; - } - - if ($params !== NULL && ! is_array($params)) - { - $params = NULL; - } - - $this->_ci_load_library($library, $params, $object_name); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Model Loader - * - * Loads and instantiates models. - * - * @param mixed $model Model name - * @param string $name An optional object name to assign to - * @param bool $db_conn An optional database connection configuration to initialize - * @return object - */ - public function model($model, $name = '', $db_conn = FALSE) - { - if (empty($model)) - { - return $this; - } - elseif (is_array($model)) - { - foreach ($model as $key => $value) - { - is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); - } - - return $this; - } - - $path = ''; - - // Is the model in a sub-folder? If so, parse out the filename and path. - if (($last_slash = strrpos($model, '/')) !== FALSE) - { - // The path is in front of the last slash - $path = substr($model, 0, ++$last_slash); - - // And the model name behind it - $model = substr($model, $last_slash); - } - - if (empty($name)) - { - $name = $model; - } - - if (in_array($name, $this->_ci_models, TRUE)) - { - return $this; - } - - $CI =& get_instance(); - if (isset($CI->$name)) - { - throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name); - } - - if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) - { - if ($db_conn === TRUE) - { - $db_conn = ''; - } - - $this->database($db_conn, FALSE, TRUE); - } - - // Note: All of the code under this condition used to be just: - // - // load_class('Model', 'core'); - // - // However, load_class() instantiates classes - // to cache them for later use and that prevents - // MY_Model from being an abstract class and is - // sub-optimal otherwise anyway. - if ( ! class_exists('CI_Model', FALSE)) - { - $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; - if (file_exists($app_path.'Model.php')) - { - require_once($app_path.'Model.php'); - if ( ! class_exists('CI_Model', FALSE)) - { - throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model"); - } - - log_message('info', 'CI_Model class loaded'); - } - elseif ( ! class_exists('CI_Model', FALSE)) - { - require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php'); - } - - $class = config_item('subclass_prefix').'Model'; - if (file_exists($app_path.$class.'.php')) - { - require_once($app_path.$class.'.php'); - if ( ! class_exists($class, FALSE)) - { - throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); - } - - log_message('info', config_item('subclass_prefix').'Model class loaded'); - } - } - - $model = ucfirst($model); - if ( ! class_exists($model, FALSE)) - { - foreach ($this->_ci_model_paths as $mod_path) - { - if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) - { - continue; - } - - require_once($mod_path.'models/'.$path.$model.'.php'); - if ( ! class_exists($model, FALSE)) - { - throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model); - } - - break; - } - - if ( ! class_exists($model, FALSE)) - { - throw new RuntimeException('Unable to locate the model you have specified: '.$model); - } - } - elseif ( ! is_subclass_of($model, 'CI_Model')) - { - throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model"); - } - - $this->_ci_models[] = $name; - $model = new $model(); - $CI->$name = $model; - log_message('info', 'Model "'.get_class($model).'" initialized'); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Database Loader - * - * @param mixed $params Database configuration options - * @param bool $return Whether to return the database object - * @param bool $query_builder Whether to enable Query Builder - * (overrides the configuration setting) - * - * @return object|bool Database object if $return is set to TRUE, - * FALSE on failure, CI_Loader instance in any other case - */ - public function database($params = '', $return = FALSE, $query_builder = NULL) - { - // Grab the super object - $CI =& get_instance(); - - // Do we even need to load the database class? - if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id)) - { - return FALSE; - } - - require_once(BASEPATH.'database/DB.php'); - - if ($return === TRUE) - { - return DB($params, $query_builder); - } - - // Initialize the db variable. Needed to prevent - // reference errors with some configurations - $CI->db = ''; - - // Load the DB class - $CI->db =& DB($params, $query_builder); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Utilities Class - * - * @param object $db Database object - * @param bool $return Whether to return the DB Utilities class object or not - * @return object - */ - public function dbutil($db = NULL, $return = FALSE) - { - $CI =& get_instance(); - - if ( ! is_object($db) OR ! ($db instanceof CI_DB)) - { - class_exists('CI_DB', FALSE) OR $this->database(); - $db =& $CI->db; - } - - require_once(BASEPATH.'database/DB_utility.php'); - require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php'); - $class = 'CI_DB_'.$db->dbdriver.'_utility'; - - if ($return === TRUE) - { - return new $class($db); - } - - $CI->dbutil = new $class($db); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Forge Class - * - * @param object $db Database object - * @param bool $return Whether to return the DB Forge class object or not - * @return object - */ - public function dbforge($db = NULL, $return = FALSE) - { - $CI =& get_instance(); - if ( ! is_object($db) OR ! ($db instanceof CI_DB)) - { - class_exists('CI_DB', FALSE) OR $this->database(); - $db =& $CI->db; - } - - require_once(BASEPATH.'database/DB_forge.php'); - require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php'); - - if ( ! empty($db->subdriver)) - { - $driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php'; - if (file_exists($driver_path)) - { - require_once($driver_path); - $class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge'; - } - } - else - { - $class = 'CI_DB_'.$db->dbdriver.'_forge'; - } - - if ($return === TRUE) - { - return new $class($db); - } - - $CI->dbforge = new $class($db); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * View Loader - * - * Loads "view" files. - * - * @param string $view View name - * @param array $vars An associative array of data - * to be extracted for use in the view - * @param bool $return Whether to return the view output - * or leave it to the Output class - * @return object|string - */ - public function view($view, $vars = array(), $return = FALSE) - { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Generic File Loader - * - * @param string $path File path - * @param bool $return Whether to return the file output - * @return object|string - */ - public function file($path, $return = FALSE) - { - return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Set Variables - * - * Once variables are set they become available within - * the controller class and its "view" files. - * - * @param array|object|string $vars - * An associative array or object containing values - * to be set, or a value's name if string - * @param string $val Value to set, only used if $vars is a string - * @return object - */ - public function vars($vars, $val = '') - { - $vars = is_string($vars) - ? array($vars => $val) - : $this->_ci_prepare_view_vars($vars); - - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Clear Cached Variables - * - * Clears the cached variables. - * - * @return CI_Loader - */ - public function clear_vars() - { - $this->_ci_cached_vars = array(); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Variable - * - * Check if a variable is set and retrieve it. - * - * @param string $key Variable name - * @return mixed The variable or NULL if not found - */ - public function get_var($key) - { - return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL; - } - - // -------------------------------------------------------------------- - - /** - * Get Variables - * - * Retrieves all loaded variables. - * - * @return array - */ - public function get_vars() - { - return $this->_ci_cached_vars; - } - - // -------------------------------------------------------------------- - - /** - * Helper Loader - * - * @param string|string[] $helpers Helper name(s) - * @return object - */ - public function helper($helpers = array()) - { - is_array($helpers) OR $helpers = array($helpers); - foreach ($helpers as &$helper) - { - $filename = basename($helper); - $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); - $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper'; - $helper = $filepath.$filename; - - if (isset($this->_ci_helpers[$helper])) - { - continue; - } - - // Is this a helper extension request? - $ext_helper = config_item('subclass_prefix').$filename; - $ext_loaded = FALSE; - foreach ($this->_ci_helper_paths as $path) - { - if (file_exists($path.'helpers/'.$ext_helper.'.php')) - { - include_once($path.'helpers/'.$ext_helper.'.php'); - $ext_loaded = TRUE; - } - } - - // If we have loaded extensions - check if the base one is here - if ($ext_loaded === TRUE) - { - $base_helper = BASEPATH.'helpers/'.$helper.'.php'; - if ( ! file_exists($base_helper)) - { - show_error('Unable to load the requested file: helpers/'.$helper.'.php'); - } - - include_once($base_helper); - $this->_ci_helpers[$helper] = TRUE; - log_message('info', 'Helper loaded: '.$helper); - continue; - } - - // No extensions found ... try loading regular helpers and/or overrides - foreach ($this->_ci_helper_paths as $path) - { - if (file_exists($path.'helpers/'.$helper.'.php')) - { - include_once($path.'helpers/'.$helper.'.php'); - - $this->_ci_helpers[$helper] = TRUE; - log_message('info', 'Helper loaded: '.$helper); - break; - } - } - - // unable to load the helper - if ( ! isset($this->_ci_helpers[$helper])) - { - show_error('Unable to load the requested file: helpers/'.$helper.'.php'); - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load Helpers - * - * An alias for the helper() method in case the developer has - * written the plural form of it. - * - * @uses CI_Loader::helper() - * @param string|string[] $helpers Helper name(s) - * @return object - */ - public function helpers($helpers = array()) - { - return $this->helper($helpers); - } - - // -------------------------------------------------------------------- - - /** - * Language Loader - * - * Loads language files. - * - * @param string|string[] $files List of language file names to load - * @param string Language name - * @return object - */ - public function language($files, $lang = '') - { - get_instance()->lang->load($files, $lang); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Config Loader - * - * Loads a config file (an alias for CI_Config::load()). - * - * @uses CI_Config::load() - * @param string $file Configuration file name - * @param bool $use_sections Whether configuration values should be loaded into their own section - * @param bool $fail_gracefully Whether to just return FALSE or display an error message - * @return bool TRUE if the file was loaded correctly or FALSE on failure - */ - public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE) - { - return get_instance()->config->load($file, $use_sections, $fail_gracefully); - } - - // -------------------------------------------------------------------- - - /** - * Driver Loader - * - * Loads a driver library. - * - * @param string|string[] $library Driver name(s) - * @param array $params Optional parameters to pass to the driver - * @param string $object_name An optional object name to assign to - * - * @return object|bool Object or FALSE on failure if $library is a string - * and $object_name is set. CI_Loader instance otherwise. - */ - public function driver($library, $params = NULL, $object_name = NULL) - { - if (is_array($library)) - { - foreach ($library as $key => $value) - { - if (is_int($key)) - { - $this->driver($value, $params); - } - else - { - $this->driver($key, $params, $value); - } - } - - return $this; - } - elseif (empty($library)) - { - return FALSE; - } - - if ( ! class_exists('CI_Driver_Library', FALSE)) - { - // We aren't instantiating an object here, just making the base class available - require BASEPATH.'libraries/Driver.php'; - } - - // We can save the loader some time since Drivers will *always* be in a subfolder, - // and typically identically named to the library - if ( ! strpos($library, '/')) - { - $library = ucfirst($library).'/'.$library; - } - - return $this->library($library, $params, $object_name); - } - - // -------------------------------------------------------------------- - - /** - * Add Package Path - * - * Prepends a parent path to the library, model, helper and config - * path arrays. - * - * @see CI_Loader::$_ci_library_paths - * @see CI_Loader::$_ci_model_paths - * @see CI_Loader::$_ci_helper_paths - * @see CI_Config::$_config_paths - * - * @param string $path Path to add - * @param bool $view_cascade (default: TRUE) - * @return object - */ - public function add_package_path($path, $view_cascade = TRUE) - { - $path = rtrim($path, '/').'/'; - - array_unshift($this->_ci_library_paths, $path); - array_unshift($this->_ci_model_paths, $path); - array_unshift($this->_ci_helper_paths, $path); - - $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths; - - // Add config file path - $config =& $this->_ci_get_component('config'); - $config->_config_paths[] = $path; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Package Paths - * - * Return a list of all package paths. - * - * @param bool $include_base Whether to include BASEPATH (default: FALSE) - * @return array - */ - public function get_package_paths($include_base = FALSE) - { - return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths; - } - - // -------------------------------------------------------------------- - - /** - * Remove Package Path - * - * Remove a path from the library, model, helper and/or config - * path arrays if it exists. If no path is provided, the most recently - * added path will be removed removed. - * - * @param string $path Path to remove - * @return object - */ - public function remove_package_path($path = '') - { - $config =& $this->_ci_get_component('config'); - - if ($path === '') - { - array_shift($this->_ci_library_paths); - array_shift($this->_ci_model_paths); - array_shift($this->_ci_helper_paths); - array_shift($this->_ci_view_paths); - array_pop($config->_config_paths); - } - else - { - $path = rtrim($path, '/').'/'; - foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var) - { - if (($key = array_search($path, $this->{$var})) !== FALSE) - { - unset($this->{$var}[$key]); - } - } - - if (isset($this->_ci_view_paths[$path.'views/'])) - { - unset($this->_ci_view_paths[$path.'views/']); - } - - if (($key = array_search($path, $config->_config_paths)) !== FALSE) - { - unset($config->_config_paths[$key]); - } - } - - // make sure the application default paths are still in the array - $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); - $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); - $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); - $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); - $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Data Loader - * - * Used to load views and files. - * - * Variables are prefixed with _ci_ to avoid symbol collision with - * variables made available to view files. - * - * @used-by CI_Loader::view() - * @used-by CI_Loader::file() - * @param array $_ci_data Data to load - * @return object - */ - protected function _ci_load($_ci_data) - { - // Set the default data variables - foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) - { - $$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE; - } - - $file_exists = FALSE; - - // Set the path to the requested file - if (is_string($_ci_path) && $_ci_path !== '') - { - $_ci_x = explode('/', $_ci_path); - $_ci_file = end($_ci_x); - } - else - { - $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); - $_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view; - - foreach ($this->_ci_view_paths as $_ci_view_file => $cascade) - { - if (file_exists($_ci_view_file.$_ci_file)) - { - $_ci_path = $_ci_view_file.$_ci_file; - $file_exists = TRUE; - break; - } - - if ( ! $cascade) - { - break; - } - } - } - - if ( ! $file_exists && ! file_exists($_ci_path)) - { - show_error('Unable to load the requested file: '.$_ci_file); - } - - // This allows anything loaded using $this->load (views, files, etc.) - // to become accessible from within the Controller and Model functions. - $_ci_CI =& get_instance(); - foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) - { - if ( ! isset($this->$_ci_key)) - { - $this->$_ci_key =& $_ci_CI->$_ci_key; - } - } - - /* - * Extract and cache variables - * - * You can either set variables using the dedicated $this->load->vars() - * function or via the second parameter of this function. We'll merge - * the two types and cache them so that views that are embedded within - * other views can have access to these variables. - */ - empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - extract($this->_ci_cached_vars); - - /* - * Buffer the output - * - * We buffer the output for two reasons: - * 1. Speed. You get a significant speed boost. - * 2. So that the final rendered template can be post-processed by - * the output class. Why do we need post processing? For one thing, - * in order to show the elapsed page load time. Unless we can - * intercept the content right before it's sent to the browser and - * then stop the timer it won't be accurate. - */ - ob_start(); - - // If the PHP installation does not support short tags we'll - // do a little string replacement, changing the short tags - // to standard PHP echo statements. - if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE) - { - echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace(' $this->_ci_ob_level + 1) - { - ob_end_flush(); - } - else - { - $_ci_CI->output->append_output(ob_get_contents()); - @ob_end_clean(); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Library Loader - * - * @used-by CI_Loader::library() - * @uses CI_Loader::_ci_init_library() - * - * @param string $class Class name to load - * @param mixed $params Optional parameters to pass to the class constructor - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_load_library($class, $params = NULL, $object_name = NULL) - { - // Get the class name, and while we're at it trim any slashes. - // The directory path can be included as part of the class name, - // but we don't want a leading slash - $class = str_replace('.php', '', trim($class, '/')); - - // Was the path included with the class name? - // We look for a slash to determine this - if (($last_slash = strrpos($class, '/')) !== FALSE) - { - // Extract the path - $subdir = substr($class, 0, ++$last_slash); - - // Get the filename from the path - $class = substr($class, $last_slash); - } - else - { - $subdir = ''; - } - - $class = ucfirst($class); - - // Is this a stock library? There are a few special conditions if so ... - if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php')) - { - return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); - } - - // Safety: Was the class already loaded by a previous call? - if (class_exists($class, FALSE)) - { - $property = $object_name; - if (empty($property)) - { - $property = strtolower($class); - isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; - } - - $CI =& get_instance(); - if (isset($CI->$property)) - { - log_message('debug', $class.' class already loaded. Second attempt ignored.'); - return; - } - - return $this->_ci_init_library($class, '', $params, $object_name); - } - - // Let's search for the requested library file and load it. - foreach ($this->_ci_library_paths as $path) - { - // BASEPATH has already been checked for - if ($path === BASEPATH) - { - continue; - } - - $filepath = $path.'libraries/'.$subdir.$class.'.php'; - // Does the file exist? No? Bummer... - if ( ! file_exists($filepath)) - { - continue; - } - - include_once($filepath); - return $this->_ci_init_library($class, '', $params, $object_name); - } - - // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? - if ($subdir === '') - { - return $this->_ci_load_library($class.'/'.$class, $params, $object_name); - } - - // If we got this far we were unable to find the requested class. - log_message('error', 'Unable to load the requested class: '.$class); - show_error('Unable to load the requested class: '.$class); - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Stock Library Loader - * - * @used-by CI_Loader::_ci_load_library() - * @uses CI_Loader::_ci_init_library() - * - * @param string $library_name Library name to load - * @param string $file_path Path to the library filename, relative to libraries/ - * @param mixed $params Optional parameters to pass to the class constructor - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name) - { - $prefix = 'CI_'; - - if (class_exists($prefix.$library_name, FALSE)) - { - if (class_exists(config_item('subclass_prefix').$library_name, FALSE)) - { - $prefix = config_item('subclass_prefix'); - } - - $property = $object_name; - if (empty($property)) - { - $property = strtolower($library_name); - isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; - } - - $CI =& get_instance(); - if ( ! isset($CI->$property)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - log_message('debug', $library_name.' class already loaded. Second attempt ignored.'); - return; - } - - $paths = $this->_ci_library_paths; - array_pop($paths); // BASEPATH - array_pop($paths); // APPPATH (needs to be the first path checked) - array_unshift($paths, APPPATH); - - foreach ($paths as $path) - { - if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php')) - { - // Override - include_once($path); - if (class_exists($prefix.$library_name, FALSE)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name); - } - } - - include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php'); - - // Check for extensions - $subclass = config_item('subclass_prefix').$library_name; - foreach ($paths as $path) - { - if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php')) - { - include_once($path); - if (class_exists($subclass, FALSE)) - { - $prefix = config_item('subclass_prefix'); - break; - } - - log_message('debug', $path.' exists, but does not declare '.$subclass); - } - } - - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Library Instantiator - * - * @used-by CI_Loader::_ci_load_stock_library() - * @used-by CI_Loader::_ci_load_library() - * - * @param string $class Class name - * @param string $prefix Class name prefix - * @param array|null|bool $config Optional configuration to pass to the class constructor: - * FALSE to skip; - * NULL to search in config paths; - * array containing configuration data - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL) - { - // Is there an associated config file for this class? Note: these should always be lowercase - if ($config === NULL) - { - // Fetch the config paths containing any package paths - $config_component = $this->_ci_get_component('config'); - - if (is_array($config_component->_config_paths)) - { - $found = FALSE; - foreach ($config_component->_config_paths as $path) - { - // We test for both uppercase and lowercase, for servers that - // are case-sensitive with regard to file names. Load global first, - // override with environment next - if (file_exists($path.'config/'.strtolower($class).'.php')) - { - include($path.'config/'.strtolower($class).'.php'); - $found = TRUE; - } - elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php')) - { - include($path.'config/'.ucfirst(strtolower($class)).'.php'); - $found = TRUE; - } - - if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) - { - include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); - $found = TRUE; - } - elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) - { - include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); - $found = TRUE; - } - - // Break on the first found configuration, thus package - // files are not overridden by default paths - if ($found === TRUE) - { - break; - } - } - } - } - - $class_name = $prefix.$class; - - // Is the class name valid? - if ( ! class_exists($class_name, FALSE)) - { - log_message('error', 'Non-existent class: '.$class_name); - show_error('Non-existent class: '.$class_name); - } - - // Set the variable name we will assign the class to - // Was a custom class name supplied? If so we'll use it - if (empty($object_name)) - { - $object_name = strtolower($class); - if (isset($this->_ci_varmap[$object_name])) - { - $object_name = $this->_ci_varmap[$object_name]; - } - } - - // Don't overwrite existing properties - $CI =& get_instance(); - if (isset($CI->$object_name)) - { - if ($CI->$object_name instanceof $class_name) - { - log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted."); - return; - } - - show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance."); - } - - // Save the class name and object name - $this->_ci_classes[$object_name] = $class; - - // Instantiate the class - $CI->$object_name = isset($config) - ? new $class_name($config) - : new $class_name(); - } - - // -------------------------------------------------------------------- - - /** - * CI Autoloader - * - * Loads component listed in the config/autoload.php file. - * - * @used-by CI_Loader::initialize() - * @return void - */ - protected function _ci_autoloader() - { - if (file_exists(APPPATH.'config/autoload.php')) - { - include(APPPATH.'config/autoload.php'); - } - - if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) - { - include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); - } - - if ( ! isset($autoload)) - { - return; - } - - // Autoload packages - if (isset($autoload['packages'])) - { - foreach ($autoload['packages'] as $package_path) - { - $this->add_package_path($package_path); - } - } - - // Load any custom config file - if (count($autoload['config']) > 0) - { - foreach ($autoload['config'] as $val) - { - $this->config($val); - } - } - - // Autoload helpers and languages - foreach (array('helper', 'language') as $type) - { - if (isset($autoload[$type]) && count($autoload[$type]) > 0) - { - $this->$type($autoload[$type]); - } - } - - // Autoload drivers - if (isset($autoload['drivers'])) - { - $this->driver($autoload['drivers']); - } - - // Load libraries - if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) - { - // Load the database driver. - if (in_array('database', $autoload['libraries'])) - { - $this->database(); - $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); - } - - // Load all other libraries - $this->library($autoload['libraries']); - } - - // Autoload models - if (isset($autoload['model'])) - { - $this->model($autoload['model']); - } - } - - // -------------------------------------------------------------------- - - /** - * Prepare variables for _ci_vars, to be later extract()-ed inside views - * - * Converts objects to associative arrays and filters-out internal - * variable names (i.e. keys prefixed with '_ci_'). - * - * @param mixed $vars - * @return array - */ - protected function _ci_prepare_view_vars($vars) - { - if ( ! is_array($vars)) - { - $vars = is_object($vars) - ? get_object_vars($vars) - : array(); - } - - foreach (array_keys($vars) as $key) - { - if (strncmp($key, '_ci_', 4) === 0) - { - unset($vars[$key]); - } - } - - return $vars; - } - - // -------------------------------------------------------------------- - - /** - * CI Component getter - * - * Get a reference to a specific library or model. - * - * @param string $component Component name - * @return bool - */ - protected function &_ci_get_component($component) - { - $CI =& get_instance(); - return $CI->$component; - } +class CI_Loader +{ + + // All these are set automatically. Don't mess with them. + /** + * Nesting level of the output buffering mechanism + * + * @var int + */ + protected $_ci_ob_level; + + /** + * List of paths to load views from + * + * @var array + */ + protected $_ci_view_paths = array(VIEWPATH => true); + + /** + * List of paths to load libraries from + * + * @var array + */ + protected $_ci_library_paths = array(APPPATH, BASEPATH); + + /** + * List of paths to load models from + * + * @var array + */ + protected $_ci_model_paths = array(APPPATH); + + /** + * List of paths to load helpers from + * + * @var array + */ + protected $_ci_helper_paths = array(APPPATH, BASEPATH); + + /** + * List of cached variables + * + * @var array + */ + protected $_ci_cached_vars = array(); + + /** + * List of loaded classes + * + * @var array + */ + protected $_ci_classes = array(); + + /** + * List of loaded models + * + * @var array + */ + protected $_ci_models = array(); + + /** + * List of loaded helpers + * + * @var array + */ + protected $_ci_helpers = array(); + + /** + * List of class name mappings + * + * @var array + */ + protected $_ci_varmap = array( + 'unit_test' => 'unit', + 'user_agent' => 'agent' + ); + + // -------------------------------------------------------------------- + + /** + * Class constructor + * + * Sets component load paths, gets the initial output buffering level. + * + * @return void + */ + public function __construct() + { + $this->_ci_ob_level = ob_get_level(); + $this->_ci_classes =& is_loaded(); + + log_message('info', 'Loader Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * Initializer + * + * @return void + * @uses CI_Loader::_ci_autoloader() + * @used-by CI_Controller::__construct() + * @todo Figure out a way to move this to the constructor + * without breaking *package_path*() methods. + */ + public function initialize() + { + $this->_ci_autoloader(); + } + + // -------------------------------------------------------------------- + + /** + * Is Loaded + * + * A utility method to test if a class is in the self::$_ci_classes array. + * + * @used-by Mainly used by Form Helper function _get_validation_object(). + * + * @param string $class Class name to check for + * @return string|bool Class object name if loaded or FALSE + */ + public function is_loaded($class) + { + return array_search(ucfirst($class), $this->_ci_classes, true); + } + + // -------------------------------------------------------------------- + + /** + * Library Loader + * + * Loads and instantiates libraries. + * Designed to be called from application controllers. + * + * @param mixed $library Library name + * @param array $params Optional parameters to pass to the library class constructor + * @param string $object_name An optional object name to assign to + * @return object + */ + public function library($library, $params = null, $object_name = null) + { + if (empty($library)) { + return $this; + } elseif (is_array($library)) { + foreach ($library as $key => $value) { + if (is_int($key)) { + $this->library($value, $params); + } else { + $this->library($key, $params, $value); + } + } + + return $this; + } + + if ($params !== null && !is_array($params)) { + $params = null; + } + + $this->_ci_load_library($library, $params, $object_name); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Model Loader + * + * Loads and instantiates models. + * + * @param mixed $model Model name + * @param string $name An optional object name to assign to + * @param bool $db_conn An optional database connection configuration to initialize + * @return object + */ + public function model($model, $name = '', $db_conn = false) + { + if (empty($model)) { + return $this; + } elseif (is_array($model)) { + foreach ($model as $key => $value) { + is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); + } + + return $this; + } + + $path = ''; + + // Is the model in a sub-folder? If so, parse out the filename and path. + if (($last_slash = strrpos($model, '/')) !== false) { + // The path is in front of the last slash + $path = substr($model, 0, ++$last_slash); + + // And the model name behind it + $model = substr($model, $last_slash); + } + + if (empty($name)) { + $name = $model; + } + + if (in_array($name, $this->_ci_models, true)) { + return $this; + } + + $CI =& get_instance(); + if (isset($CI->$name)) { + throw new RuntimeException( + 'The model name you are loading is the name of a resource that is already being used: ' . $name + ); + } + + if ($db_conn !== false && !class_exists('CI_DB', false)) { + if ($db_conn === true) { + $db_conn = ''; + } + + $this->database($db_conn, false, true); + } + + // Note: All of the code under this condition used to be just: + // + // load_class('Model', 'core'); + // + // However, load_class() instantiates classes + // to cache them for later use and that prevents + // MY_Model from being an abstract class and is + // sub-optimal otherwise anyway. + if (!class_exists('CI_Model', false)) { + $app_path = APPPATH . 'core' . DIRECTORY_SEPARATOR; + if (file_exists($app_path . 'Model.php')) { + require_once($app_path . 'Model.php'); + if (!class_exists('CI_Model', false)) { + throw new RuntimeException($app_path . "Model.php exists, but doesn't declare class CI_Model"); + } + + log_message('info', 'CI_Model class loaded'); + } elseif (!class_exists('CI_Model', false)) { + require_once(BASEPATH . 'core' . DIRECTORY_SEPARATOR . 'Model.php'); + } + + $class = config_item('subclass_prefix') . 'Model'; + if (file_exists($app_path . $class . '.php')) { + require_once($app_path . $class . '.php'); + if (!class_exists($class, false)) { + throw new RuntimeException($app_path . $class . ".php exists, but doesn't declare class " . $class); + } + + log_message('info', config_item('subclass_prefix') . 'Model class loaded'); + } + } + + $model = ucfirst($model); + if (!class_exists($model, false)) { + foreach ($this->_ci_model_paths as $mod_path) { + if (!file_exists($mod_path . 'models/' . $path . $model . '.php')) { + continue; + } + + require_once($mod_path . 'models/' . $path . $model . '.php'); + if (!class_exists($model, false)) { + throw new RuntimeException( + $mod_path . "models/" . $path . $model . ".php exists, but doesn't declare class " . $model + ); + } + + break; + } + + if (!class_exists($model, false)) { + throw new RuntimeException('Unable to locate the model you have specified: ' . $model); + } + } elseif (!is_subclass_of($model, 'CI_Model')) { + throw new RuntimeException("Class " . $model . " already exists and doesn't extend CI_Model"); + } + + $this->_ci_models[] = $name; + $model = new $model(); + $CI->$name = $model; + log_message('info', 'Model "' . get_class($model) . '" initialized'); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Database Loader + * + * @param mixed $params Database configuration options + * @param bool $return Whether to return the database object + * @param bool $query_builder Whether to enable Query Builder + * (overrides the configuration setting) + * + * @return object|bool Database object if $return is set to TRUE, + * FALSE on failure, CI_Loader instance in any other case + */ + public function database($params = '', $return = false, $query_builder = null) + { + // Grab the super object + $CI =& get_instance(); + + // Do we even need to load the database class? + if ($return === false && $query_builder === null && isset($CI->db) && is_object( + $CI->db + ) && !empty($CI->db->conn_id)) { + return false; + } + + require_once(BASEPATH . 'database/DB.php'); + + if ($return === true) { + return DB($params, $query_builder); + } + + // Initialize the db variable. Needed to prevent + // reference errors with some configurations + $CI->db = ''; + + // Load the DB class + $CI->db =& DB($params, $query_builder); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Load the Database Utilities Class + * + * @param object $db Database object + * @param bool $return Whether to return the DB Utilities class object or not + * @return object + */ + public function dbutil($db = null, $return = false) + { + $CI =& get_instance(); + + if (!is_object($db) or !($db instanceof CI_DB)) { + class_exists('CI_DB', false) or $this->database(); + $db =& $CI->db; + } + + require_once(BASEPATH . 'database/DB_utility.php'); + require_once(BASEPATH . 'database/drivers/' . $db->dbdriver . '/' . $db->dbdriver . '_utility.php'); + $class = 'CI_DB_' . $db->dbdriver . '_utility'; + + if ($return === true) { + return new $class($db); + } + + $CI->dbutil = new $class($db); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Load the Database Forge Class + * + * @param object $db Database object + * @param bool $return Whether to return the DB Forge class object or not + * @return object + */ + public function dbforge($db = null, $return = false) + { + $CI =& get_instance(); + if (!is_object($db) or !($db instanceof CI_DB)) { + class_exists('CI_DB', false) or $this->database(); + $db =& $CI->db; + } + + require_once(BASEPATH . 'database/DB_forge.php'); + require_once(BASEPATH . 'database/drivers/' . $db->dbdriver . '/' . $db->dbdriver . '_forge.php'); + + if (!empty($db->subdriver)) { + $driver_path = BASEPATH . 'database/drivers/' . $db->dbdriver . '/subdrivers/' . $db->dbdriver . '_' . $db->subdriver . '_forge.php'; + if (file_exists($driver_path)) { + require_once($driver_path); + $class = 'CI_DB_' . $db->dbdriver . '_' . $db->subdriver . '_forge'; + } + } else { + $class = 'CI_DB_' . $db->dbdriver . '_forge'; + } + + if ($return === true) { + return new $class($db); + } + + $CI->dbforge = new $class($db); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * View Loader + * + * Loads "view" files. + * + * @param string $view View name + * @param array $vars An associative array of data + * to be extracted for use in the view + * @param bool $return Whether to return the view output + * or leave it to the Output class + * @return object|string + */ + public function view($view, $vars = array(), $return = false) + { + return $this->_ci_load( + array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return) + ); + } + + // -------------------------------------------------------------------- + + /** + * Generic File Loader + * + * @param string $path File path + * @param bool $return Whether to return the file output + * @return object|string + */ + public function file($path, $return = false) + { + return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Set Variables + * + * Once variables are set they become available within + * the controller class and its "view" files. + * + * @param array|object|string $vars + * An associative array or object containing values + * to be set, or a value's name if string + * @param string $val Value to set, only used if $vars is a string + * @return object + */ + public function vars($vars, $val = '') + { + $vars = is_string($vars) + ? array($vars => $val) + : $this->_ci_prepare_view_vars($vars); + + foreach ($vars as $key => $val) { + $this->_ci_cached_vars[$key] = $val; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Clear Cached Variables + * + * Clears the cached variables. + * + * @return CI_Loader + */ + public function clear_vars() + { + $this->_ci_cached_vars = array(); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Get Variable + * + * Check if a variable is set and retrieve it. + * + * @param string $key Variable name + * @return mixed The variable or NULL if not found + */ + public function get_var($key) + { + return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : null; + } + + // -------------------------------------------------------------------- + + /** + * Get Variables + * + * Retrieves all loaded variables. + * + * @return array + */ + public function get_vars() + { + return $this->_ci_cached_vars; + } + + // -------------------------------------------------------------------- + + /** + * Helper Loader + * + * @param string|string[] $helpers Helper name(s) + * @return object + */ + public function helper($helpers = array()) + { + is_array($helpers) or $helpers = array($helpers); + foreach ($helpers as &$helper) { + $filename = basename($helper); + $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); + $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)) . '_helper'; + $helper = $filepath . $filename; + + if (isset($this->_ci_helpers[$helper])) { + continue; + } + + // Is this a helper extension request? + $ext_helper = config_item('subclass_prefix') . $filename; + $ext_loaded = false; + foreach ($this->_ci_helper_paths as $path) { + if (file_exists($path . 'helpers/' . $ext_helper . '.php')) { + include_once($path . 'helpers/' . $ext_helper . '.php'); + $ext_loaded = true; + } + } + + // If we have loaded extensions - check if the base one is here + if ($ext_loaded === true) { + $base_helper = BASEPATH . 'helpers/' . $helper . '.php'; + if (!file_exists($base_helper)) { + show_error('Unable to load the requested file: helpers/' . $helper . '.php'); + } + + include_once($base_helper); + $this->_ci_helpers[$helper] = true; + log_message('info', 'Helper loaded: ' . $helper); + continue; + } + + // No extensions found ... try loading regular helpers and/or overrides + foreach ($this->_ci_helper_paths as $path) { + if (file_exists($path . 'helpers/' . $helper . '.php')) { + include_once($path . 'helpers/' . $helper . '.php'); + + $this->_ci_helpers[$helper] = true; + log_message('info', 'Helper loaded: ' . $helper); + break; + } + } + + // unable to load the helper + if (!isset($this->_ci_helpers[$helper])) { + show_error('Unable to load the requested file: helpers/' . $helper . '.php'); + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Load Helpers + * + * An alias for the helper() method in case the developer has + * written the plural form of it. + * + * @param string|string[] $helpers Helper name(s) + * @return object + * @uses CI_Loader::helper() + */ + public function helpers($helpers = array()) + { + return $this->helper($helpers); + } + + // -------------------------------------------------------------------- + + /** + * Language Loader + * + * Loads language files. + * + * @param string|string[] $files List of language file names to load + * @param string Language name + * @return object + */ + public function language($files, $lang = '') + { + get_instance()->lang->load($files, $lang); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Config Loader + * + * Loads a config file (an alias for CI_Config::load()). + * + * @param string $file Configuration file name + * @param bool $use_sections Whether configuration values should be loaded into their own section + * @param bool $fail_gracefully Whether to just return FALSE or display an error message + * @return bool TRUE if the file was loaded correctly or FALSE on failure + * @uses CI_Config::load() + */ + public function config($file, $use_sections = false, $fail_gracefully = false) + { + return get_instance()->config->load($file, $use_sections, $fail_gracefully); + } + + // -------------------------------------------------------------------- + + /** + * Driver Loader + * + * Loads a driver library. + * + * @param string|string[] $library Driver name(s) + * @param array $params Optional parameters to pass to the driver + * @param string $object_name An optional object name to assign to + * + * @return object|bool Object or FALSE on failure if $library is a string + * and $object_name is set. CI_Loader instance otherwise. + */ + public function driver($library, $params = null, $object_name = null) + { + if (is_array($library)) { + foreach ($library as $key => $value) { + if (is_int($key)) { + $this->driver($value, $params); + } else { + $this->driver($key, $params, $value); + } + } + + return $this; + } elseif (empty($library)) { + return false; + } + + if (!class_exists('CI_Driver_Library', false)) { + // We aren't instantiating an object here, just making the base class available + require BASEPATH . 'libraries/Driver.php'; + } + + // We can save the loader some time since Drivers will *always* be in a subfolder, + // and typically identically named to the library + if (!strpos($library, '/')) { + $library = ucfirst($library) . '/' . $library; + } + + return $this->library($library, $params, $object_name); + } + + // -------------------------------------------------------------------- + + /** + * Add Package Path + * + * Prepends a parent path to the library, model, helper and config + * path arrays. + * + * @param string $path Path to add + * @param bool $view_cascade (default: TRUE) + * @return object + * @see CI_Config::$_config_paths + * + * @see CI_Loader::$_ci_library_paths + * @see CI_Loader::$_ci_model_paths + * @see CI_Loader::$_ci_helper_paths + */ + public function add_package_path($path, $view_cascade = true) + { + $path = rtrim($path, '/') . '/'; + + array_unshift($this->_ci_library_paths, $path); + array_unshift($this->_ci_model_paths, $path); + array_unshift($this->_ci_helper_paths, $path); + + $this->_ci_view_paths = array($path . 'views/' => $view_cascade) + $this->_ci_view_paths; + + // Add config file path + $config =& $this->_ci_get_component('config'); + $config->_config_paths[] = $path; + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Get Package Paths + * + * Return a list of all package paths. + * + * @param bool $include_base Whether to include BASEPATH (default: FALSE) + * @return array + */ + public function get_package_paths($include_base = false) + { + return ($include_base === true) ? $this->_ci_library_paths : $this->_ci_model_paths; + } + + // -------------------------------------------------------------------- + + /** + * Remove Package Path + * + * Remove a path from the library, model, helper and/or config + * path arrays if it exists. If no path is provided, the most recently + * added path will be removed removed. + * + * @param string $path Path to remove + * @return object + */ + public function remove_package_path($path = '') + { + $config =& $this->_ci_get_component('config'); + + if ($path === '') { + array_shift($this->_ci_library_paths); + array_shift($this->_ci_model_paths); + array_shift($this->_ci_helper_paths); + array_shift($this->_ci_view_paths); + array_pop($config->_config_paths); + } else { + $path = rtrim($path, '/') . '/'; + foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var) { + if (($key = array_search($path, $this->{$var})) !== false) { + unset($this->{$var}[$key]); + } + } + + if (isset($this->_ci_view_paths[$path . 'views/'])) { + unset($this->_ci_view_paths[$path . 'views/']); + } + + if (($key = array_search($path, $config->_config_paths)) !== false) { + unset($config->_config_paths[$key]); + } + } + + // make sure the application default paths are still in the array + $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); + $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); + $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); + $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH . 'views/' => true)); + $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Data Loader + * + * Used to load views and files. + * + * Variables are prefixed with _ci_ to avoid symbol collision with + * variables made available to view files. + * + * @used-by CI_Loader::view() + * @used-by CI_Loader::file() + * @param array $_ci_data Data to load + * @return object + */ + protected function _ci_load($_ci_data) + { + // Set the default data variables + foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) { + $$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : false; + } + + $file_exists = false; + + // Set the path to the requested file + if (is_string($_ci_path) && $_ci_path !== '') { + $_ci_x = explode('/', $_ci_path); + $_ci_file = end($_ci_x); + } else { + $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); + $_ci_file = ($_ci_ext === '') ? $_ci_view . '.php' : $_ci_view; + + foreach ($this->_ci_view_paths as $_ci_view_file => $cascade) { + if (file_exists($_ci_view_file . $_ci_file)) { + $_ci_path = $_ci_view_file . $_ci_file; + $file_exists = true; + break; + } + + if (!$cascade) { + break; + } + } + } + + if (!$file_exists && !file_exists($_ci_path)) { + show_error('Unable to load the requested file: ' . $_ci_file); + } + + // This allows anything loaded using $this->load (views, files, etc.) + // to become accessible from within the Controller and Model functions. + $_ci_CI =& get_instance(); + foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) { + if (!isset($this->$_ci_key)) { + $this->$_ci_key =& $_ci_CI->$_ci_key; + } + } + + /* + * Extract and cache variables + * + * You can either set variables using the dedicated $this->load->vars() + * function or via the second parameter of this function. We'll merge + * the two types and cache them so that views that are embedded within + * other views can have access to these variables. + */ + empty($_ci_vars) or $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); + extract($this->_ci_cached_vars); + + /* + * Buffer the output + * + * We buffer the output for two reasons: + * 1. Speed. You get a significant speed boost. + * 2. So that the final rendered template can be post-processed by + * the output class. Why do we need post processing? For one thing, + * in order to show the elapsed page load time. Unless we can + * intercept the content right before it's sent to the browser and + * then stop the timer it won't be accurate. + */ + ob_start(); + + // If the PHP installation does not support short tags we'll + // do a little string replacement, changing the short tags + // to standard PHP echo statements. + if (!is_php('5.4') && !ini_get('short_open_tag') && config_item('rewrite_short_tags') === true) { + echo eval( + '?>' . preg_replace( + '/;*\s*\?>/', + '; ?>', + str_replace(' $this->_ci_ob_level + 1) { + ob_end_flush(); + } else { + $_ci_CI->output->append_output(ob_get_contents()); + @ob_end_clean(); + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Library Loader + * + * @used-by CI_Loader::library() + * @param string $class Class name to load + * @param mixed $params Optional parameters to pass to the class constructor + * @param string $object_name Optional object name to assign to + * @return void + * @uses CI_Loader::_ci_init_library() + * + */ + protected function _ci_load_library($class, $params = null, $object_name = null) + { + // Get the class name, and while we're at it trim any slashes. + // The directory path can be included as part of the class name, + // but we don't want a leading slash + $class = str_replace('.php', '', trim($class, '/')); + + // Was the path included with the class name? + // We look for a slash to determine this + if (($last_slash = strrpos($class, '/')) !== false) { + // Extract the path + $subdir = substr($class, 0, ++$last_slash); + + // Get the filename from the path + $class = substr($class, $last_slash); + } else { + $subdir = ''; + } + + $class = ucfirst($class); + + // Is this a stock library? There are a few special conditions if so ... + if (file_exists(BASEPATH . 'libraries/' . $subdir . $class . '.php')) { + return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); + } + + // Safety: Was the class already loaded by a previous call? + if (class_exists($class, false)) { + $property = $object_name; + if (empty($property)) { + $property = strtolower($class); + isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; + } + + $CI =& get_instance(); + if (isset($CI->$property)) { + log_message('debug', $class . ' class already loaded. Second attempt ignored.'); + return; + } + + return $this->_ci_init_library($class, '', $params, $object_name); + } + + // Let's search for the requested library file and load it. + foreach ($this->_ci_library_paths as $path) { + // BASEPATH has already been checked for + if ($path === BASEPATH) { + continue; + } + + $filepath = $path . 'libraries/' . $subdir . $class . '.php'; + // Does the file exist? No? Bummer... + if (!file_exists($filepath)) { + continue; + } + + include_once($filepath); + return $this->_ci_init_library($class, '', $params, $object_name); + } + + // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? + if ($subdir === '') { + return $this->_ci_load_library($class . '/' . $class, $params, $object_name); + } + + // If we got this far we were unable to find the requested class. + log_message('error', 'Unable to load the requested class: ' . $class); + show_error('Unable to load the requested class: ' . $class); + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Stock Library Loader + * + * @used-by CI_Loader::_ci_load_library() + * @param string $library_name Library name to load + * @param string $file_path Path to the library filename, relative to libraries/ + * @param mixed $params Optional parameters to pass to the class constructor + * @param string $object_name Optional object name to assign to + * @return void + * @uses CI_Loader::_ci_init_library() + * + */ + protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name) + { + $prefix = 'CI_'; + + if (class_exists($prefix . $library_name, false)) { + if (class_exists(config_item('subclass_prefix') . $library_name, false)) { + $prefix = config_item('subclass_prefix'); + } + + $property = $object_name; + if (empty($property)) { + $property = strtolower($library_name); + isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; + } + + $CI =& get_instance(); + if (!isset($CI->$property)) { + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); + } + + log_message('debug', $library_name . ' class already loaded. Second attempt ignored.'); + return; + } + + $paths = $this->_ci_library_paths; + array_pop($paths); // BASEPATH + array_pop($paths); // APPPATH (needs to be the first path checked) + array_unshift($paths, APPPATH); + + foreach ($paths as $path) { + if (file_exists($path = $path . 'libraries/' . $file_path . $library_name . '.php')) { + // Override + include_once($path); + if (class_exists($prefix . $library_name, false)) { + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); + } + + log_message('debug', $path . ' exists, but does not declare ' . $prefix . $library_name); + } + } + + include_once(BASEPATH . 'libraries/' . $file_path . $library_name . '.php'); + + // Check for extensions + $subclass = config_item('subclass_prefix') . $library_name; + foreach ($paths as $path) { + if (file_exists($path = $path . 'libraries/' . $file_path . $subclass . '.php')) { + include_once($path); + if (class_exists($subclass, false)) { + $prefix = config_item('subclass_prefix'); + break; + } + + log_message('debug', $path . ' exists, but does not declare ' . $subclass); + } + } + + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Library Instantiator + * + * @used-by CI_Loader::_ci_load_stock_library() + * @used-by CI_Loader::_ci_load_library() + * + * @param string $class Class name + * @param string $prefix Class name prefix + * @param array|null|bool $config Optional configuration to pass to the class constructor: + * FALSE to skip; + * NULL to search in config paths; + * array containing configuration data + * @param string $object_name Optional object name to assign to + * @return void + */ + protected function _ci_init_library($class, $prefix, $config = false, $object_name = null) + { + // Is there an associated config file for this class? Note: these should always be lowercase + if ($config === null) { + // Fetch the config paths containing any package paths + $config_component = $this->_ci_get_component('config'); + + if (is_array($config_component->_config_paths)) { + $found = false; + foreach ($config_component->_config_paths as $path) { + // We test for both uppercase and lowercase, for servers that + // are case-sensitive with regard to file names. Load global first, + // override with environment next + if (file_exists($path . 'config/' . strtolower($class) . '.php')) { + include($path . 'config/' . strtolower($class) . '.php'); + $found = true; + } elseif (file_exists($path . 'config/' . ucfirst(strtolower($class)) . '.php')) { + include($path . 'config/' . ucfirst(strtolower($class)) . '.php'); + $found = true; + } + + if (file_exists($path . 'config/' . ENVIRONMENT . '/' . strtolower($class) . '.php')) { + include($path . 'config/' . ENVIRONMENT . '/' . strtolower($class) . '.php'); + $found = true; + } elseif (file_exists( + $path . 'config/' . ENVIRONMENT . '/' . ucfirst(strtolower($class)) . '.php' + )) { + include($path . 'config/' . ENVIRONMENT . '/' . ucfirst(strtolower($class)) . '.php'); + $found = true; + } + + // Break on the first found configuration, thus package + // files are not overridden by default paths + if ($found === true) { + break; + } + } + } + } + + $class_name = $prefix . $class; + + // Is the class name valid? + if (!class_exists($class_name, false)) { + log_message('error', 'Non-existent class: ' . $class_name); + show_error('Non-existent class: ' . $class_name); + } + + // Set the variable name we will assign the class to + // Was a custom class name supplied? If so we'll use it + if (empty($object_name)) { + $object_name = strtolower($class); + if (isset($this->_ci_varmap[$object_name])) { + $object_name = $this->_ci_varmap[$object_name]; + } + } + + // Don't overwrite existing properties + $CI =& get_instance(); + if (isset($CI->$object_name)) { + if ($CI->$object_name instanceof $class_name) { + log_message( + 'debug', + $class_name . " has already been instantiated as '" . $object_name . "'. Second attempt aborted." + ); + return; + } + + show_error("Resource '" . $object_name . "' already exists and is not a " . $class_name . " instance."); + } + + // Save the class name and object name + $this->_ci_classes[$object_name] = $class; + + // Instantiate the class + $CI->$object_name = isset($config) + ? new $class_name($config) + : new $class_name(); + } + + // -------------------------------------------------------------------- + + /** + * CI Autoloader + * + * Loads component listed in the config/autoload.php file. + * + * @used-by CI_Loader::initialize() + * @return void + */ + protected function _ci_autoloader() + { + if (file_exists(APPPATH . 'config/autoload.php')) { + include(APPPATH . 'config/autoload.php'); + } + + if (file_exists(APPPATH . 'config/' . ENVIRONMENT . '/autoload.php')) { + include(APPPATH . 'config/' . ENVIRONMENT . '/autoload.php'); + } + + if (!isset($autoload)) { + return; + } + + // Autoload packages + if (isset($autoload['packages'])) { + foreach ($autoload['packages'] as $package_path) { + $this->add_package_path($package_path); + } + } + + // Load any custom config file + if (count($autoload['config']) > 0) { + foreach ($autoload['config'] as $val) { + $this->config($val); + } + } + + // Autoload helpers and languages + foreach (array('helper', 'language') as $type) { + if (isset($autoload[$type]) && count($autoload[$type]) > 0) { + $this->$type($autoload[$type]); + } + } + + // Autoload drivers + if (isset($autoload['drivers'])) { + $this->driver($autoload['drivers']); + } + + // Load libraries + if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) { + // Load the database driver. + if (in_array('database', $autoload['libraries'])) { + $this->database(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); + } + + // Load all other libraries + $this->library($autoload['libraries']); + } + + // Autoload models + if (isset($autoload['model'])) { + $this->model($autoload['model']); + } + } + + // -------------------------------------------------------------------- + + /** + * Prepare variables for _ci_vars, to be later extract()-ed inside views + * + * Converts objects to associative arrays and filters-out internal + * variable names (i.e. keys prefixed with '_ci_'). + * + * @param mixed $vars + * @return array + */ + protected function _ci_prepare_view_vars($vars) + { + if (!is_array($vars)) { + $vars = is_object($vars) + ? get_object_vars($vars) + : array(); + } + + foreach (array_keys($vars) as $key) { + if (strncmp($key, '_ci_', 4) === 0) { + unset($vars[$key]); + } + } + + return $vars; + } + + // -------------------------------------------------------------------- + + /** + * CI Component getter + * + * Get a reference to a specific library or model. + * + * @param string $component Component name + * @return bool + */ + protected function &_ci_get_component($component) + { + $CI =& get_instance(); + return $CI->$component; + } }