Repository: bcit-ci/CodeIgniter
Branch: develop
Commit: 3658d731eaab
Files: 541
Total size: 3.1 MB
Directory structure:
gitextract_gk2rayde/
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ └── test-phpunit.yml
├── .gitignore
├── DCO.txt
├── application/
│ ├── .htaccess
│ ├── cache/
│ │ └── index.html
│ ├── config/
│ │ ├── autoload.php
│ │ ├── config.php
│ │ ├── constants.php
│ │ ├── database.php
│ │ ├── doctypes.php
│ │ ├── foreign_chars.php
│ │ ├── hooks.php
│ │ ├── index.html
│ │ ├── memcached.php
│ │ ├── migration.php
│ │ ├── mimes.php
│ │ ├── profiler.php
│ │ ├── routes.php
│ │ └── user_agents.php
│ ├── controllers/
│ │ ├── Welcome.php
│ │ └── index.html
│ ├── core/
│ │ └── index.html
│ ├── helpers/
│ │ └── index.html
│ ├── hooks/
│ │ └── index.html
│ ├── index.html
│ ├── language/
│ │ ├── english/
│ │ │ └── index.html
│ │ └── index.html
│ ├── libraries/
│ │ └── index.html
│ ├── logs/
│ │ └── index.html
│ ├── models/
│ │ └── index.html
│ ├── third_party/
│ │ └── index.html
│ └── views/
│ ├── errors/
│ │ ├── cli/
│ │ │ ├── error_404.php
│ │ │ ├── error_db.php
│ │ │ ├── error_exception.php
│ │ │ ├── error_general.php
│ │ │ ├── error_php.php
│ │ │ └── index.html
│ │ ├── html/
│ │ │ ├── error_404.php
│ │ │ ├── error_db.php
│ │ │ ├── error_exception.php
│ │ │ ├── error_general.php
│ │ │ ├── error_php.php
│ │ │ └── index.html
│ │ └── index.html
│ ├── index.html
│ └── welcome_message.php
├── build-release.sh
├── composer.json
├── contributing.md
├── index.php
├── license.txt
├── phpdoc.dist.xml
├── readme.rst
├── system/
│ ├── .htaccess
│ ├── core/
│ │ ├── Benchmark.php
│ │ ├── CodeIgniter.php
│ │ ├── Common.php
│ │ ├── Config.php
│ │ ├── Controller.php
│ │ ├── Exceptions.php
│ │ ├── Hooks.php
│ │ ├── Input.php
│ │ ├── Lang.php
│ │ ├── Loader.php
│ │ ├── Log.php
│ │ ├── Model.php
│ │ ├── Output.php
│ │ ├── Router.php
│ │ ├── Security.php
│ │ ├── URI.php
│ │ ├── Utf8.php
│ │ ├── compat/
│ │ │ ├── hash.php
│ │ │ ├── index.html
│ │ │ ├── mbstring.php
│ │ │ ├── password.php
│ │ │ └── standard.php
│ │ └── index.html
│ ├── database/
│ │ ├── DB.php
│ │ ├── DB_cache.php
│ │ ├── DB_driver.php
│ │ ├── DB_forge.php
│ │ ├── DB_query_builder.php
│ │ ├── DB_result.php
│ │ ├── DB_utility.php
│ │ ├── drivers/
│ │ │ ├── cubrid/
│ │ │ │ ├── cubrid_driver.php
│ │ │ │ ├── cubrid_forge.php
│ │ │ │ ├── cubrid_result.php
│ │ │ │ ├── cubrid_utility.php
│ │ │ │ └── index.html
│ │ │ ├── ibase/
│ │ │ │ ├── ibase_driver.php
│ │ │ │ ├── ibase_forge.php
│ │ │ │ ├── ibase_result.php
│ │ │ │ ├── ibase_utility.php
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ ├── mssql/
│ │ │ │ ├── index.html
│ │ │ │ ├── mssql_driver.php
│ │ │ │ ├── mssql_forge.php
│ │ │ │ ├── mssql_result.php
│ │ │ │ └── mssql_utility.php
│ │ │ ├── mysql/
│ │ │ │ ├── index.html
│ │ │ │ ├── mysql_driver.php
│ │ │ │ ├── mysql_forge.php
│ │ │ │ ├── mysql_result.php
│ │ │ │ └── mysql_utility.php
│ │ │ ├── mysqli/
│ │ │ │ ├── index.html
│ │ │ │ ├── mysqli_driver.php
│ │ │ │ ├── mysqli_forge.php
│ │ │ │ ├── mysqli_result.php
│ │ │ │ └── mysqli_utility.php
│ │ │ ├── oci8/
│ │ │ │ ├── index.html
│ │ │ │ ├── oci8_driver.php
│ │ │ │ ├── oci8_forge.php
│ │ │ │ ├── oci8_result.php
│ │ │ │ └── oci8_utility.php
│ │ │ ├── odbc/
│ │ │ │ ├── index.html
│ │ │ │ ├── odbc_driver.php
│ │ │ │ ├── odbc_forge.php
│ │ │ │ ├── odbc_result.php
│ │ │ │ └── odbc_utility.php
│ │ │ ├── pdo/
│ │ │ │ ├── index.html
│ │ │ │ ├── pdo_driver.php
│ │ │ │ ├── pdo_forge.php
│ │ │ │ ├── pdo_result.php
│ │ │ │ ├── pdo_utility.php
│ │ │ │ └── subdrivers/
│ │ │ │ ├── index.html
│ │ │ │ ├── pdo_4d_driver.php
│ │ │ │ ├── pdo_4d_forge.php
│ │ │ │ ├── pdo_cubrid_driver.php
│ │ │ │ ├── pdo_cubrid_forge.php
│ │ │ │ ├── pdo_dblib_driver.php
│ │ │ │ ├── pdo_dblib_forge.php
│ │ │ │ ├── pdo_firebird_driver.php
│ │ │ │ ├── pdo_firebird_forge.php
│ │ │ │ ├── pdo_ibm_driver.php
│ │ │ │ ├── pdo_ibm_forge.php
│ │ │ │ ├── pdo_informix_driver.php
│ │ │ │ ├── pdo_informix_forge.php
│ │ │ │ ├── pdo_mysql_driver.php
│ │ │ │ ├── pdo_mysql_forge.php
│ │ │ │ ├── pdo_oci_driver.php
│ │ │ │ ├── pdo_oci_forge.php
│ │ │ │ ├── pdo_odbc_driver.php
│ │ │ │ ├── pdo_odbc_forge.php
│ │ │ │ ├── pdo_pgsql_driver.php
│ │ │ │ ├── pdo_pgsql_forge.php
│ │ │ │ ├── pdo_sqlite_driver.php
│ │ │ │ ├── pdo_sqlite_forge.php
│ │ │ │ ├── pdo_sqlsrv_driver.php
│ │ │ │ └── pdo_sqlsrv_forge.php
│ │ │ ├── postgre/
│ │ │ │ ├── index.html
│ │ │ │ ├── postgre_driver.php
│ │ │ │ ├── postgre_forge.php
│ │ │ │ ├── postgre_result.php
│ │ │ │ └── postgre_utility.php
│ │ │ ├── sqlite3/
│ │ │ │ ├── index.html
│ │ │ │ ├── sqlite3_driver.php
│ │ │ │ ├── sqlite3_forge.php
│ │ │ │ ├── sqlite3_result.php
│ │ │ │ └── sqlite3_utility.php
│ │ │ └── sqlsrv/
│ │ │ ├── index.html
│ │ │ ├── sqlsrv_driver.php
│ │ │ ├── sqlsrv_forge.php
│ │ │ ├── sqlsrv_result.php
│ │ │ └── sqlsrv_utility.php
│ │ └── index.html
│ ├── fonts/
│ │ └── index.html
│ ├── helpers/
│ │ ├── array_helper.php
│ │ ├── captcha_helper.php
│ │ ├── cookie_helper.php
│ │ ├── date_helper.php
│ │ ├── directory_helper.php
│ │ ├── download_helper.php
│ │ ├── file_helper.php
│ │ ├── form_helper.php
│ │ ├── html_helper.php
│ │ ├── index.html
│ │ ├── inflector_helper.php
│ │ ├── language_helper.php
│ │ ├── number_helper.php
│ │ ├── path_helper.php
│ │ ├── security_helper.php
│ │ ├── string_helper.php
│ │ ├── text_helper.php
│ │ ├── typography_helper.php
│ │ ├── url_helper.php
│ │ └── xml_helper.php
│ ├── index.html
│ ├── language/
│ │ ├── english/
│ │ │ ├── calendar_lang.php
│ │ │ ├── date_lang.php
│ │ │ ├── db_lang.php
│ │ │ ├── email_lang.php
│ │ │ ├── form_validation_lang.php
│ │ │ ├── ftp_lang.php
│ │ │ ├── imglib_lang.php
│ │ │ ├── index.html
│ │ │ ├── migration_lang.php
│ │ │ ├── number_lang.php
│ │ │ ├── pagination_lang.php
│ │ │ ├── profiler_lang.php
│ │ │ ├── unit_test_lang.php
│ │ │ └── upload_lang.php
│ │ └── index.html
│ └── libraries/
│ ├── Cache/
│ │ ├── Cache.php
│ │ ├── drivers/
│ │ │ ├── Cache_apc.php
│ │ │ ├── Cache_apcu.php
│ │ │ ├── Cache_dummy.php
│ │ │ ├── Cache_file.php
│ │ │ ├── Cache_memcached.php
│ │ │ ├── Cache_redis.php
│ │ │ ├── Cache_wincache.php
│ │ │ └── index.html
│ │ └── index.html
│ ├── Calendar.php
│ ├── Driver.php
│ ├── Email.php
│ ├── Encryption.php
│ ├── Form_validation.php
│ ├── Ftp.php
│ ├── Image_lib.php
│ ├── Migration.php
│ ├── Pagination.php
│ ├── Parser.php
│ ├── Profiler.php
│ ├── Session/
│ │ ├── CI_Session_driver_interface.php
│ │ ├── OldSessionWrapper.php
│ │ ├── PHP8SessionWrapper.php
│ │ ├── Session.php
│ │ ├── SessionUpdateTimestampHandlerInterface.php
│ │ ├── Session_driver.php
│ │ ├── drivers/
│ │ │ ├── Session_database_driver.php
│ │ │ ├── Session_files_driver.php
│ │ │ ├── Session_memcached_driver.php
│ │ │ ├── Session_redis_driver.php
│ │ │ └── index.html
│ │ └── index.html
│ ├── Table.php
│ ├── Trackback.php
│ ├── Typography.php
│ ├── Unit_test.php
│ ├── Upload.php
│ ├── User_agent.php
│ ├── Xmlrpc.php
│ ├── Xmlrpcs.php
│ ├── Zip.php
│ └── index.html
├── tests/
│ ├── Bootstrap.php
│ ├── README.md
│ ├── codeigniter/
│ │ ├── Setup_test.php
│ │ ├── core/
│ │ │ ├── Benchmark_test.php
│ │ │ ├── Common_test.php
│ │ │ ├── Config_test.php
│ │ │ ├── Input_test.php
│ │ │ ├── Lang_test.php
│ │ │ ├── Loader_test.php
│ │ │ ├── Log_test.php
│ │ │ ├── Model_test.php
│ │ │ ├── Output_test.php
│ │ │ ├── Security_test.php
│ │ │ ├── URI_test.php
│ │ │ ├── Utf8_test.php
│ │ │ └── compat/
│ │ │ ├── hash_test.php
│ │ │ ├── mbstring_test.php
│ │ │ ├── password_test.php
│ │ │ └── standard_test.php
│ │ ├── database/
│ │ │ ├── DB_driver_test.php
│ │ │ ├── DB_test.php
│ │ │ └── query_builder/
│ │ │ ├── count_test.php
│ │ │ ├── delete_test.php
│ │ │ ├── distinct_test.php
│ │ │ ├── empty_test.php
│ │ │ ├── escape_test.php
│ │ │ ├── from_test.php
│ │ │ ├── get_test.php
│ │ │ ├── group_test.php
│ │ │ ├── insert_test.php
│ │ │ ├── join_test.php
│ │ │ ├── like_test.php
│ │ │ ├── limit_test.php
│ │ │ ├── order_test.php
│ │ │ ├── select_test.php
│ │ │ ├── truncate_test.php
│ │ │ ├── update_test.php
│ │ │ └── where_test.php
│ │ ├── helpers/
│ │ │ ├── array_helper_test.php
│ │ │ ├── captcha_helper_test.php
│ │ │ ├── cookie_helper_test.php
│ │ │ ├── date_helper_test.php
│ │ │ ├── directory_helper_test.php
│ │ │ ├── download_helper_test.php
│ │ │ ├── file_helper_test.php
│ │ │ ├── form_helper_test.php
│ │ │ ├── html_helper_test.php
│ │ │ ├── inflector_helper_test.php
│ │ │ ├── language_helper_test.php
│ │ │ ├── number_helper_test.php
│ │ │ ├── path_helper_test.php
│ │ │ ├── security_helper_test.php
│ │ │ ├── string_helper_test.php
│ │ │ ├── text_helper_test.php
│ │ │ ├── url_helper_test.php
│ │ │ └── xml_helper_test.php
│ │ └── libraries/
│ │ ├── Calendar_test.php
│ │ ├── Driver_test.php
│ │ ├── Encryption_test.php
│ │ ├── Form_validation_test.php
│ │ ├── Parser_test.php
│ │ ├── Session_test.php
│ │ ├── Table_test.php
│ │ ├── Typography_test.php
│ │ ├── Upload_test.php
│ │ └── Useragent_test.php
│ ├── mocks/
│ │ ├── autoloader.php
│ │ ├── ci_testcase.php
│ │ ├── ci_testconfig.php
│ │ ├── core/
│ │ │ ├── common.php
│ │ │ ├── security.php
│ │ │ └── uri.php
│ │ ├── database/
│ │ │ ├── config/
│ │ │ │ ├── mysql.php
│ │ │ │ ├── mysqli.php
│ │ │ │ ├── pdo/
│ │ │ │ │ ├── mysql.php
│ │ │ │ │ ├── pgsql.php
│ │ │ │ │ └── sqlite.php
│ │ │ │ ├── pgsql.php
│ │ │ │ └── sqlite.php
│ │ │ ├── db/
│ │ │ │ └── driver.php
│ │ │ ├── db.php
│ │ │ ├── drivers/
│ │ │ │ ├── mysql.php
│ │ │ │ ├── mysqli.php
│ │ │ │ ├── pdo.php
│ │ │ │ ├── postgre.php
│ │ │ │ └── sqlite.php
│ │ │ └── schema/
│ │ │ └── skeleton.php
│ │ └── libraries/
│ │ ├── driver.php
│ │ ├── encryption.php
│ │ ├── session.php
│ │ └── table.php
│ ├── phpunit.xml
│ └── travis/
│ ├── mysql.phpunit.xml
│ ├── mysqli.phpunit.xml
│ ├── pdo/
│ │ ├── mysql.phpunit.xml
│ │ ├── pgsql.phpunit.xml
│ │ └── sqlite.phpunit.xml
│ ├── pgsql.phpunit.xml
│ └── sqlite.phpunit.xml
└── user_guide_src/
├── Makefile
├── README.rst
├── cilexer/
│ ├── README
│ ├── cilexer/
│ │ ├── __init__.py
│ │ └── cilexer.py
│ └── setup.py
└── source/
├── DCO.rst
├── _themes/
│ └── sphinx_rtd_theme/
│ ├── LICENSE
│ ├── __init__.py
│ ├── breadcrumbs.html
│ ├── footer.html
│ ├── layout.html
│ ├── layout_old.html
│ ├── pulldown.html
│ ├── search.html
│ ├── searchbox.html
│ ├── static/
│ │ ├── css/
│ │ │ ├── badge_only.css
│ │ │ ├── citheme.css
│ │ │ └── theme.css
│ │ ├── fonts/
│ │ │ └── FontAwesome.otf
│ │ └── js/
│ │ ├── oldtheme.js
│ │ └── theme.js
│ ├── theme.conf
│ └── versions.html
├── changelog.rst
├── conf.py
├── contributing/
│ └── index.rst
├── database/
│ ├── caching.rst
│ ├── call_function.rst
│ ├── configuration.rst
│ ├── connecting.rst
│ ├── db_driver_reference.rst
│ ├── examples.rst
│ ├── forge.rst
│ ├── helpers.rst
│ ├── index.rst
│ ├── metadata.rst
│ ├── queries.rst
│ ├── query_builder.rst
│ ├── results.rst
│ ├── transactions.rst
│ └── utilities.rst
├── documentation/
│ └── index.rst
├── general/
│ ├── alternative_php.rst
│ ├── ancillary_classes.rst
│ ├── autoloader.rst
│ ├── caching.rst
│ ├── cli.rst
│ ├── common_functions.rst
│ ├── compatibility_functions.rst
│ ├── controllers.rst
│ ├── core_classes.rst
│ ├── creating_drivers.rst
│ ├── creating_libraries.rst
│ ├── credits.rst
│ ├── drivers.rst
│ ├── environments.rst
│ ├── errors.rst
│ ├── helpers.rst
│ ├── hooks.rst
│ ├── index.rst
│ ├── libraries.rst
│ ├── managing_apps.rst
│ ├── models.rst
│ ├── profiling.rst
│ ├── requirements.rst
│ ├── reserved_names.rst
│ ├── routing.rst
│ ├── security.rst
│ ├── styleguide.rst
│ ├── urls.rst
│ ├── views.rst
│ └── welcome.rst
├── helpers/
│ ├── array_helper.rst
│ ├── captcha_helper.rst
│ ├── cookie_helper.rst
│ ├── date_helper.rst
│ ├── directory_helper.rst
│ ├── download_helper.rst
│ ├── file_helper.rst
│ ├── form_helper.rst
│ ├── html_helper.rst
│ ├── index.rst
│ ├── inflector_helper.rst
│ ├── language_helper.rst
│ ├── number_helper.rst
│ ├── path_helper.rst
│ ├── security_helper.rst
│ ├── string_helper.rst
│ ├── text_helper.rst
│ ├── typography_helper.rst
│ ├── url_helper.rst
│ └── xml_helper.rst
├── index.rst
├── installation/
│ ├── downloads.rst
│ ├── index.rst
│ ├── troubleshooting.rst
│ ├── upgrade_120.rst
│ ├── upgrade_130.rst
│ ├── upgrade_131.rst
│ ├── upgrade_132.rst
│ ├── upgrade_133.rst
│ ├── upgrade_140.rst
│ ├── upgrade_141.rst
│ ├── upgrade_150.rst
│ ├── upgrade_152.rst
│ ├── upgrade_153.rst
│ ├── upgrade_154.rst
│ ├── upgrade_160.rst
│ ├── upgrade_161.rst
│ ├── upgrade_162.rst
│ ├── upgrade_163.rst
│ ├── upgrade_170.rst
│ ├── upgrade_171.rst
│ ├── upgrade_172.rst
│ ├── upgrade_200.rst
│ ├── upgrade_201.rst
│ ├── upgrade_202.rst
│ ├── upgrade_203.rst
│ ├── upgrade_210.rst
│ ├── upgrade_211.rst
│ ├── upgrade_212.rst
│ ├── upgrade_213.rst
│ ├── upgrade_214.rst
│ ├── upgrade_220.rst
│ ├── upgrade_221.rst
│ ├── upgrade_222.rst
│ ├── upgrade_223.rst
│ ├── upgrade_300.rst
│ ├── upgrade_301.rst
│ ├── upgrade_302.rst
│ ├── upgrade_303.rst
│ ├── upgrade_304.rst
│ ├── upgrade_305.rst
│ ├── upgrade_306.rst
│ ├── upgrade_310.rst
│ ├── upgrade_311.rst
│ ├── upgrade_3110.rst
│ ├── upgrade_3111.rst
│ ├── upgrade_3112.rst
│ ├── upgrade_3113.rst
│ ├── upgrade_3114.rst
│ ├── upgrade_312.rst
│ ├── upgrade_313.rst
│ ├── upgrade_314.rst
│ ├── upgrade_315.rst
│ ├── upgrade_316.rst
│ ├── upgrade_317.rst
│ ├── upgrade_318.rst
│ ├── upgrade_319.rst
│ ├── upgrade_320.rst
│ ├── upgrade_b11.rst
│ └── upgrading.rst
├── libraries/
│ ├── benchmark.rst
│ ├── caching.rst
│ ├── calendar.rst
│ ├── config.rst
│ ├── email.rst
│ ├── encryption.rst
│ ├── file_uploading.rst
│ ├── form_validation.rst
│ ├── ftp.rst
│ ├── image_lib.rst
│ ├── index.rst
│ ├── input.rst
│ ├── language.rst
│ ├── loader.rst
│ ├── migration.rst
│ ├── output.rst
│ ├── pagination.rst
│ ├── parser.rst
│ ├── security.rst
│ ├── sessions.rst
│ ├── table.rst
│ ├── trackback.rst
│ ├── typography.rst
│ ├── unit_testing.rst
│ ├── uri.rst
│ ├── user_agent.rst
│ ├── xmlrpc.rst
│ └── zip.rst
├── license.rst
├── overview/
│ ├── appflow.rst
│ ├── at_a_glance.rst
│ ├── features.rst
│ ├── getting_started.rst
│ ├── goals.rst
│ ├── index.rst
│ └── mvc.rst
└── tutorial/
├── conclusion.rst
├── create_news_items.rst
├── index.rst
├── news_section.rst
└── static_pages.rst
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*]
charset = utf-8
# Tab indentation (no size specified)
indent_style = tab
================================================
FILE: .gitattributes
================================================
# This file tells which files and directories should be ignored and
# NOT downloaded when using composer to pull down a project with
# the --prefer-dist option selected. Used to remove development
# specific files so user has a clean download.
# git files
.gitattributes export-ignore
# .gitignore
# helper config files
.travis.yml export-ignore
phpdoc.dist.xml export-ignore
# Misc other files
readme.rst
# They don't want all of our tests...
tests/codeigniter/ export-ignore
tests/travis/ export-ignore
# User Guide source files and compiled files
user_guide_src export-ignore
user_guide export-ignore
================================================
FILE: .github/workflows/test-phpunit.yml
================================================
name: PHPUnit
on: [push, pull_request]
permissions:
contents: read
jobs:
tests:
runs-on: ubuntu-22.04
if: "!contains(github.event.head_commit.message, '[ci skip]')"
env:
PHP_INI_VALUES: assert.exception=1, zend.assertions=1
strategy:
fail-fast: false
matrix:
php: [ '8.1', '8.0', '7.4', '7.3', '7.2', '7.1', '7.0', '5.6', '5.5', '5.4']
DB: [ 'pdo/mysql', 'pdo/pgsql', 'pdo/sqlite', 'mysqli', 'pgsql', 'sqlite' ]
compiler: [ default ]
include:
- php: '8.1'
DB: 'pdo/mysql'
compiler: jit
- php: '8.1'
DB: 'pdo/pgsql'
compiler: jit
- php: '8.1'
DB: 'pdo/sqlite'
compiler: jit
- php: '8.1'
DB: 'mysqli'
compiler: jit
- php: '8.1'
DB: 'pgsql'
compiler: jit
- php: '8.1'
DB: 'sqlite'
compiler: jit
- php: '8.0'
DB: 'pdo/mysql'
compiler: jit
- php: '8.0'
DB: 'pdo/pgsql'
compiler: jit
- php: '8.0'
DB: 'pdo/sqlite'
compiler: jit
- php: '8.0'
DB: 'mysqli'
compiler: jit
- php: '8.0'
DB: 'pgsql'
compiler: jit
- php: '8.0'
DB: 'sqlite'
compiler: jit
- php: '5.6'
DB: 'mysql'
compiler: default
- php: '5.5'
DB: 'mysql'
compiler: default
- php: '5.4'
DB: 'mysql'
compiler: default
services:
postgres:
image: postgres:12
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: ci_test
ports:
- 5432:5432
options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_USER: travis
MYSQL_PASSWORD: travis
MYSQL_DATABASE: ci_test
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Override PHP ini values for JIT compiler
if: matrix.compiler == 'jit'
run: echo "PHP_INI_VALUES::assert.exception=1, zend.assertions=1, opcache.enable=1, opcache.enable_cli=1, opcache.optimization_level=-1, opcache.jit=1255, opcache.jit_buffer_size=64M" >> $GITHUB_ENV
- name: Install PHP${{ matrix.php }} - DB ${{ matrix.DB }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer, pecl
extensions: imagick, sqlite3, pgsql, mysqli, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, mbstring
ini-values: ${{ env.PHP_INI_VALUES }}
coverage: xdebug
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install composer dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: PHPUnit Test
run: |
php -d error_reporting=E_ALL -d zend.enable_gc=0 -d date.timezone=UTC -d mbstring.func_overload=7 -d mbstring.internal_encoding=UTF-8 vendor/bin/phpunit --coverage-text --configuration tests/travis/${{ matrix.DB }}.phpunit.xml
env:
XDEBUG_MODE: coverage
================================================
FILE: .gitignore
================================================
.DS_Store
application/cache/*
!application/cache/index.html
application/logs/*
!application/logs/index.html
!application/*/.htaccess
composer.lock
tests/mocks/database/ci_test.sqlite
user_guide_src/build/*
user_guide_src/cilexer/build/*
user_guide_src/cilexer/dist/*
user_guide_src/cilexer/pycilexer.egg-info/*
/vendor/
# IDE Files
#-------------------------
/nbproject/
.idea/*
## Sublime Text cache files
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
*.sublime-workspace
*.sublime-project
/tests/tests/
/tests/results/
================================================
FILE: DCO.txt
================================================
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(1) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(2) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(3) The contribution was provided directly to me by some other
person who certified (1), (2) or (3) and I have not modified
it.
(4) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
================================================
FILE: application/.htaccess
================================================
Directory access is forbidden.
================================================ FILE: application/config/autoload.php ================================================ 'ua'); */ $autoload['libraries'] = array(); /* | ------------------------------------------------------------------- | Auto-load Drivers | ------------------------------------------------------------------- | These classes are located in system/libraries/ or in your | application/libraries/ directory, but are also placed inside their | own subdirectory and they extend the CI_Driver_Library class. They | offer multiple interchangeable driver options. | | Prototype: | | $autoload['drivers'] = array('cache'); | | You can also supply an alternative property name to be assigned in | the controller: | | $autoload['drivers'] = array('cache' => 'cch'); | */ $autoload['drivers'] = array(); /* | ------------------------------------------------------------------- | Auto-load Helper Files | ------------------------------------------------------------------- | Prototype: | | $autoload['helper'] = array('url', 'file'); */ $autoload['helper'] = array(); /* | ------------------------------------------------------------------- | Auto-load Config files | ------------------------------------------------------------------- | Prototype: | | $autoload['config'] = array('config1', 'config2'); | | NOTE: This item is intended for use ONLY if you have created custom | config files. Otherwise, leave it blank. | */ $autoload['config'] = array(); /* | ------------------------------------------------------------------- | Auto-load Language files | ------------------------------------------------------------------- | Prototype: | | $autoload['language'] = array('lang1', 'lang2'); | | NOTE: Do not include the "_lang" part of your file. For example | "codeigniter_lang.php" would be referenced as array('codeigniter'); | */ $autoload['language'] = array(); /* | ------------------------------------------------------------------- | Auto-load Models | ------------------------------------------------------------------- | Prototype: | | $autoload['model'] = array('first_model', 'second_model'); | | You can also supply an alternative model name to be assigned | in the controller: | | $autoload['model'] = array('first_model' => 'first'); */ $autoload['model'] = array(); ================================================ FILE: application/config/config.php ================================================ ]+$/i | | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! | | Note: This option is ignored for CLI requests. | */ $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; /* |-------------------------------------------------------------------------- | Enable Query Strings |-------------------------------------------------------------------------- | | By default CodeIgniter uses search-engine friendly segment based URLs: | example.com/who/what/where/ | | You can optionally enable standard query string based URLs: | example.com?who=me&what=something&where=here | | Options are: TRUE or FALSE (boolean) | | The other items let you set the query string 'words' that will | invoke your controllers and its functions: | example.com/index.php?c=controller&m=function | | Please note that some of the helpers won't work as expected when | this feature is enabled, since CodeIgniter is designed primarily to | use segment based URLs. | */ $config['enable_query_strings'] = FALSE; $config['controller_trigger'] = 'c'; $config['function_trigger'] = 'm'; $config['directory_trigger'] = 'd'; /* |-------------------------------------------------------------------------- | Error Logging Threshold |-------------------------------------------------------------------------- | | You can enable error logging by setting a threshold over zero. The | threshold determines what gets logged. Threshold options are: | | 0 = Disables logging, Error logging TURNED OFF | 1 = Error Messages (including PHP errors) | 2 = Debug Messages | 3 = Informational Messages | 4 = All Messages | | You can also pass an array with threshold levels to show individual error types | | array(2) = Debug Messages, without Error Messages | | For a live site you'll usually only enable Errors (1) to be logged otherwise | your log files will fill up very fast. | */ $config['log_threshold'] = 0; /* |-------------------------------------------------------------------------- | Error Logging Directory Path |-------------------------------------------------------------------------- | | Leave this BLANK unless you would like to set something other than the default | application/logs/ directory. Use a full server path. | */ $config['log_path'] = ''; /* |-------------------------------------------------------------------------- | Error Logging FILENAME |-------------------------------------------------------------------------- | | Leave this BLANK unless you would like to set something other than the default | 'log-'.date('Y-m-d').'.php'. No DIRECTORY_SEPARATOR(s), just the filename. | */ $config['log_filename'] = ''; /* |-------------------------------------------------------------------------- | Log File Permissions |-------------------------------------------------------------------------- | | The file system permissions to be applied on newly created log files. | | IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal | integer notation (i.e. 0700, 0644, etc.) */ $config['log_file_permissions'] = 0644; /* |-------------------------------------------------------------------------- | Date Format for Logs |-------------------------------------------------------------------------- | | Each item that is logged has an associated date. You can use PHP date | codes to set your own date formatting | */ $config['log_date_format'] = 'Y-m-d H:i:s'; /* |-------------------------------------------------------------------------- | Error Views Directory Path |-------------------------------------------------------------------------- | | Leave this BLANK unless you would like to set something other than the default | application/views/errors/ directory. Use a full server path. | */ $config['error_views_path'] = ''; /* |-------------------------------------------------------------------------- | Cache Directory Path |-------------------------------------------------------------------------- | | Leave this BLANK unless you would like to set something other than the default | application/cache/ directory. Use a full server path. | */ $config['cache_path'] = ''; /* |-------------------------------------------------------------------------- | Cache Include Query String |-------------------------------------------------------------------------- | | Whether to take the URL query string into consideration when generating | output cache files. Valid options are: | | FALSE = Disabled | TRUE = Enabled, take all query parameters into account. | Please be aware that this may result in numerous cache | files generated for the same page over and over again. | array('q') = Enabled, but only take into account the specified list | of query parameters. | */ $config['cache_query_string'] = FALSE; /* |-------------------------------------------------------------------------- | Encryption Key |-------------------------------------------------------------------------- | | If you use the Encryption class, you must set an encryption key. | See the user guide for more info. | | https://codeigniter.com/userguide3/libraries/encryption.html | */ $config['encryption_key'] = ''; /* |-------------------------------------------------------------------------- | Session Variables |-------------------------------------------------------------------------- | | 'sess_driver' | | The storage driver to use: files, database, redis, memcached | | 'sess_cookie_name' | | The session cookie name, must contain only [0-9a-z_-] characters | | 'sess_samesite' | | Session cookie SameSite attribute: Lax (default), Strict or None | | 'sess_expiration' | | The number of SECONDS you want the session to last. | Setting to 0 (zero) means expire when the browser is closed. | | 'sess_save_path' | | The location to save sessions to, driver dependent. | | For the 'files' driver, it's a path to a writable directory. | WARNING: Only absolute paths are supported! | | For the 'database' driver, it's a table name. | Please read up the manual for the format with other session drivers. | | IMPORTANT: You are REQUIRED to set a valid save path! | | 'sess_match_ip' | | Whether to match the user's IP address when reading the session data. | | WARNING: If you're using the database driver, don't forget to update | your session table's PRIMARY KEY when changing this setting. | | 'sess_time_to_update' | | How many seconds between CI regenerating the session ID. | | 'sess_regenerate_destroy' | | Whether to destroy session data associated with the old session ID | when auto-regenerating the session ID. When set to FALSE, the data | will be later deleted by the garbage collector. | | Other session cookie settings are shared with the rest of the application, | except for 'cookie_prefix' and 'cookie_httponly', which are ignored here. | */ $config['sess_driver'] = 'files'; $config['sess_cookie_name'] = 'ci_session'; $config['sess_samesite'] = 'Lax'; $config['sess_expiration'] = 7200; $config['sess_save_path'] = NULL; $config['sess_match_ip'] = FALSE; $config['sess_time_to_update'] = 300; $config['sess_regenerate_destroy'] = FALSE; /* |-------------------------------------------------------------------------- | Cookie Related Variables |-------------------------------------------------------------------------- | | 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions | 'cookie_domain' = Set to .your-domain.com for site-wide cookies | 'cookie_path' = Typically will be a forward slash | 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. | 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) | 'cookie_samesite' = Cookie's samesite attribute (Lax, Strict or None) | | Note: These settings (with the exception of 'cookie_prefix' and | 'cookie_httponly') will also affect sessions. | */ $config['cookie_prefix'] = ''; $config['cookie_domain'] = ''; $config['cookie_path'] = '/'; $config['cookie_secure'] = FALSE; $config['cookie_httponly'] = FALSE; $config['cookie_samesite'] = 'Lax'; /* |-------------------------------------------------------------------------- | Cross Site Request Forgery |-------------------------------------------------------------------------- | Enables a CSRF cookie token to be set. When set to TRUE, token will be | checked on a submitted form. If you are accepting user data, it is strongly | recommended CSRF protection be enabled. | | 'csrf_token_name' = The token name | 'csrf_cookie_name' = The cookie name | 'csrf_expire' = The number in seconds the token should expire. | 'csrf_regenerate' = Regenerate token on every submission | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks */ $config['csrf_protection'] = FALSE; $config['csrf_token_name'] = 'csrf_test_name'; $config['csrf_cookie_name'] = 'csrf_cookie_name'; $config['csrf_expire'] = 7200; $config['csrf_regenerate'] = TRUE; $config['csrf_exclude_uris'] = array(); /* |-------------------------------------------------------------------------- | Output Compression |-------------------------------------------------------------------------- | | Enables Gzip output compression for faster page loads. When enabled, | the output class will test whether your server supports Gzip. | Even if it does, however, not all browsers support compression | so enable only if you are reasonably sure your visitors can handle it. | | Only used if zlib.output_compression is turned off in your php.ini. | Please do not use it together with httpd-level output compression. | | VERY IMPORTANT: If you are getting a blank page when compression is enabled it | means you are prematurely outputting something to your browser. It could | even be a line of whitespace at the end of one of your scripts. For | compression to work, nothing can be sent before the output buffer is called | by the output class. Do not 'echo' any values with compression enabled. | */ $config['compress_output'] = FALSE; /* |-------------------------------------------------------------------------- | Master Time Reference |-------------------------------------------------------------------------- | | Options are 'local' or any PHP supported timezone. This preference tells | the system whether to use your server's local time as the master 'now' | reference, or convert it to the configured one timezone. See the 'date | helper' page of the user guide for information regarding date handling. | */ $config['time_reference'] = 'local'; /* |-------------------------------------------------------------------------- | Reverse Proxy IPs |-------------------------------------------------------------------------- | | If your server is behind a reverse proxy, you must whitelist the proxy | IP addresses from which CodeIgniter should trust headers such as | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify | the visitor's IP address. | | You can use both an array or a comma-separated list of proxy addresses, | as well as specifying whole subnets. Here are a few examples: | | Comma-separated: '10.0.1.200,192.168.5.0/24' | Array: array('10.0.1.200', '192.168.5.0/24') */ $config['proxy_ips'] = ''; ================================================ FILE: application/config/constants.php ================================================ db->last_query() and profiling of DB queries. | When you run a query, with this setting set to TRUE (default), | CodeIgniter will store the SQL statement for debugging purposes. | However, this may cause high memory usage, especially if you run | a lot of SQL queries ... disable this to avoid that problem. | | The $active_group variable lets you choose which connection group to | make active. By default there is only one group (the 'default' group). */ $active_group = 'default'; $db['default'] = array( 'dsn' => '', 'hostname' => 'localhost', 'username' => '', 'password' => '', 'database' => '', 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => (ENVIRONMENT !== 'production'), 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, 'failover' => array(), 'save_queries' => TRUE ); ================================================ FILE: application/config/doctypes.php ================================================ '', 'xhtml1-strict' => '', 'xhtml1-trans' => '', 'xhtml1-frame' => '', 'xhtml-basic11' => '', 'html5' => '', 'html4-strict' => '', 'html4-trans' => '', 'html4-frame' => '', 'mathml1' => '', 'mathml2' => '', 'svg10' => '', 'svg11' => '', 'svg11-basic' => '', 'svg11-tiny' => '', 'xhtml-math-svg-xh' => '', 'xhtml-math-svg-sh' => '', 'xhtml-rdfa-1' => '', 'xhtml-rdfa-2' => '' ); ================================================ FILE: application/config/foreign_chars.php ================================================ 'ae', '/ö|œ/' => 'oe', '/ü/' => 'ue', '/Ä/' => 'Ae', '/Ü/' => 'Ue', '/Ö/' => 'Oe', '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A', '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a', '/Б/' => 'B', '/б/' => 'b', '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', '/ç|ć|ĉ|ċ|č/' => 'c', '/Д|Δ/' => 'D', '/д|δ/' => 'd', '/Ð|Ď|Đ/' => 'Dj', '/ð|ď|đ/' => 'dj', '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E', '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e', '/Ф/' => 'F', '/ф/' => 'f', '/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G', '/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g', '/Ĥ|Ħ/' => 'H', '/ĥ|ħ/' => 'h', '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I', '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i', '/Ĵ/' => 'J', '/ĵ/' => 'j', '/Θ/' => 'TH', '/θ/' => 'th', '/Ķ|Κ|К/' => 'K', '/ķ|κ|к/' => 'k', '/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L', '/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l', '/М/' => 'M', '/м/' => 'm', '/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N', '/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n', '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O', '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o', '/П/' => 'P', '/п/' => 'p', '/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R', '/ŕ|ŗ|ř|ρ|р/' => 'r', '/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S', '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's', '/Ț|Ţ|Ť|Ŧ|Τ|Т/' => 'T', '/ț|ţ|ť|ŧ|τ|т/' => 't', '/Þ|þ/' => 'th', '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', '/Ƴ|Ɏ|Ỵ|Ẏ|Ӳ|Ӯ|Ў|Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y', '/ẙ|ʏ|ƴ|ɏ|ỵ|ẏ|ӳ|ӯ|ў|ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y', '/В/' => 'V', '/в/' => 'v', '/Ŵ/' => 'W', '/ŵ/' => 'w', '/Φ/' => 'F', '/φ/' => 'f', '/Χ/' => 'CH', '/χ/' => 'ch', '/Ź|Ż|Ž|Ζ|З/' => 'Z', '/ź|ż|ž|ζ|з/' => 'z', '/Æ|Ǽ/' => 'AE', '/ß/' => 'ss', '/IJ/' => 'IJ', '/ij/' => 'ij', '/Œ/' => 'OE', '/ƒ/' => 'f', '/Ξ/' => 'KS', '/ξ/' => 'ks', '/Π/' => 'P', '/π/' => 'p', '/Β/' => 'V', '/β/' => 'v', '/Μ/' => 'M', '/μ/' => 'm', '/Ψ/' => 'PS', '/ψ/' => 'ps', '/Ё/' => 'Yo', '/ё/' => 'yo', '/Є/' => 'Ye', '/є/' => 'ye', '/Ї/' => 'Yi', '/Ж/' => 'Zh', '/ж/' => 'zh', '/Х/' => 'Kh', '/х/' => 'kh', '/Ц/' => 'Ts', '/ц/' => 'ts', '/Ч/' => 'Ch', '/ч/' => 'ch', '/Ш/' => 'Sh', '/ш/' => 'sh', '/Щ/' => 'Shch', '/щ/' => 'shch', '/Ъ|ъ|Ь|ь/' => '', '/Ю/' => 'Yu', '/ю/' => 'yu', '/Я/' => 'Ya', '/я/' => 'ya' ); ================================================ FILE: application/config/hooks.php ================================================Directory access is forbidden.
================================================ FILE: application/config/memcached.php ================================================ array( 'hostname' => '127.0.0.1', 'port' => '11211', 'weight' => '1', ), ); ================================================ FILE: application/config/migration.php ================================================ migration->current() this is the version that schema will | be upgraded / downgraded to. | */ $config['migration_version'] = 0; /* |-------------------------------------------------------------------------- | Migrations Path |-------------------------------------------------------------------------- | | Path to your migrations folder. | Typically, it will be within your application path. | Also, writing permission is required within the migrations path. | */ $config['migration_path'] = APPPATH.'migrations/'; ================================================ FILE: application/config/mimes.php ================================================ array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), 'cpt' => 'application/mac-compactpro', 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'), 'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'), 'dms' => 'application/octet-stream', 'lha' => 'application/octet-stream', 'lzh' => 'application/octet-stream', 'exe' => array('application/octet-stream', 'application/x-msdownload'), 'class' => 'application/octet-stream', 'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'), 'so' => 'application/octet-stream', 'sea' => 'application/octet-stream', 'dll' => 'application/octet-stream', 'oda' => 'application/oda', 'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'), 'ai' => array('application/pdf', 'application/postscript'), 'eps' => 'application/postscript', 'ps' => 'application/postscript', 'smi' => 'application/smil', 'smil' => 'application/smil', 'mif' => 'application/vnd.mif', 'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'), 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'), 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'), 'wbxml' => 'application/wbxml', 'wmlc' => 'application/wmlc', 'dcr' => 'application/x-director', 'dir' => 'application/x-director', 'dxr' => 'application/x-director', 'dvi' => 'application/x-dvi', 'gtar' => 'application/x-gtar', 'gz' => 'application/x-gzip', 'gzip' => 'application/x-gzip', 'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'), 'php4' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php', 'phtml' => 'application/x-httpd-php', 'phps' => 'application/x-httpd-php-source', 'js' => array('application/x-javascript', 'text/plain'), 'swf' => 'application/x-shockwave-flash', 'sit' => 'application/x-stuffit', 'tar' => 'application/x-tar', 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), 'z' => 'application/x-compress', 'xhtml' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml', 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), 'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'), 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mpga' => 'audio/mpeg', 'mp2' => 'audio/mpeg', 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), 'aif' => array('audio/x-aiff', 'audio/aiff'), 'aiff' => array('audio/x-aiff', 'audio/aiff'), 'aifc' => 'audio/x-aiff', 'ram' => 'audio/x-pn-realaudio', 'rm' => 'audio/x-pn-realaudio', 'rpm' => 'audio/x-pn-realaudio-plugin', 'ra' => 'audio/x-realaudio', 'rv' => 'video/vnd.rn-realvideo', 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'), 'gif' => 'image/gif', 'jpeg' => array('image/jpeg', 'image/pjpeg'), 'jpg' => array('image/jpeg', 'image/pjpeg'), 'jpe' => array('image/jpeg', 'image/pjpeg'), 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), 'png' => array('image/png', 'image/x-png'), 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'heic' => 'image/heic', 'heif' => 'image/heif', 'css' => array('text/css', 'text/plain'), 'html' => array('text/html', 'text/plain'), 'htm' => array('text/html', 'text/plain'), 'shtml' => array('text/html', 'text/plain'), 'txt' => 'text/plain', 'text' => 'text/plain', 'log' => array('text/plain', 'text/x-log'), 'rtx' => 'text/richtext', 'rtf' => 'text/rtf', 'xml' => array('application/xml', 'text/xml', 'text/plain'), 'xsl' => array('application/xml', 'text/xsl', 'text/xml'), 'mpeg' => 'video/mpeg', 'mpg' => 'video/mpeg', 'mpe' => 'video/mpeg', 'qt' => 'video/quicktime', 'mov' => 'video/quicktime', 'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'), 'movie' => 'video/x-sgi-movie', 'doc' => array('application/msword', 'application/vnd.ms-office'), 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'), 'dot' => array('application/msword', 'application/vnd.ms-office'), 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'), 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'), 'word' => array('application/msword', 'application/octet-stream'), 'xl' => 'application/excel', 'eml' => 'message/rfc822', 'json' => array('application/json', 'text/json'), 'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'), 'p10' => array('application/x-pkcs10', 'application/pkcs10'), 'p12' => 'application/x-pkcs12', 'p7a' => 'application/x-pkcs7-signature', 'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), 'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), 'p7r' => 'application/x-pkcs7-certreqresp', 'p7s' => 'application/pkcs7-signature', 'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'), 'crl' => array('application/pkix-crl', 'application/pkcs-crl'), 'der' => 'application/x-x509-ca-cert', 'kdb' => 'application/octet-stream', 'pgp' => 'application/pgp', 'gpg' => 'application/gpg-keys', 'sst' => 'application/octet-stream', 'csr' => 'application/octet-stream', 'rsa' => 'application/x-pkcs7', 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), '3g2' => 'video/3gpp2', '3gp' => array('video/3gp', 'video/3gpp'), 'mp4' => 'video/mp4', 'm4a' => 'audio/x-m4a', 'f4v' => array('video/mp4', 'video/x-f4v'), 'flv' => 'video/x-flv', 'webm' => 'video/webm', 'aac' => array('audio/x-aac', 'audio/aac'), 'm4u' => 'application/vnd.mpegurl', 'm3u' => 'text/plain', 'xspf' => 'application/xspf+xml', 'vlc' => 'application/videolan', 'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'), 'au' => 'audio/x-au', 'ac3' => 'audio/ac3', 'flac' => 'audio/x-flac', 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), 'ics' => 'text/calendar', 'ical' => 'text/calendar', 'zsh' => 'text/x-scriptzsh', '7z' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), '7zip' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'), 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), 'svg' => array('image/svg+xml', 'image/svg', 'application/xml', 'text/xml'), 'vcf' => 'text/x-vcard', 'srt' => array('text/srt', 'text/plain'), 'vtt' => array('text/vtt', 'text/plain'), 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'), 'odc' => 'application/vnd.oasis.opendocument.chart', 'otc' => 'application/vnd.oasis.opendocument.chart-template', 'odf' => 'application/vnd.oasis.opendocument.formula', 'otf' => 'application/vnd.oasis.opendocument.formula-template', 'odg' => 'application/vnd.oasis.opendocument.graphics', 'otg' => 'application/vnd.oasis.opendocument.graphics-template', 'odi' => 'application/vnd.oasis.opendocument.image', 'oti' => 'application/vnd.oasis.opendocument.image-template', 'odp' => 'application/vnd.oasis.opendocument.presentation', 'otp' => 'application/vnd.oasis.opendocument.presentation-template', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', 'odt' => 'application/vnd.oasis.opendocument.text', 'odm' => 'application/vnd.oasis.opendocument.text-master', 'ott' => 'application/vnd.oasis.opendocument.text-template', 'oth' => 'application/vnd.oasis.opendocument.text-web' ); ================================================ FILE: application/config/profiler.php ================================================ my_controller/index | my-controller/my-method -> my_controller/my_method */ $route['default_controller'] = 'welcome'; $route['404_override'] = ''; $route['translate_uri_dashes'] = FALSE; ================================================ FILE: application/config/user_agents.php ================================================ 'Windows 10', 'windows nt 6.3' => 'Windows 8.1', 'windows nt 6.2' => 'Windows 8', 'windows nt 6.1' => 'Windows 7', 'windows nt 6.0' => 'Windows Vista', 'windows nt 5.2' => 'Windows 2003', 'windows nt 5.1' => 'Windows XP', 'windows nt 5.0' => 'Windows 2000', 'windows nt 4.0' => 'Windows NT 4.0', 'winnt4.0' => 'Windows NT 4.0', 'winnt 4.0' => 'Windows NT', 'winnt' => 'Windows NT', 'windows 98' => 'Windows 98', 'win98' => 'Windows 98', 'windows 95' => 'Windows 95', 'win95' => 'Windows 95', 'windows phone' => 'Windows Phone', 'windows' => 'Unknown Windows OS', 'android' => 'Android', 'blackberry' => 'BlackBerry', 'iphone' => 'iOS', 'ipad' => 'iOS', 'ipod' => 'iOS', 'os x' => 'Mac OS X', 'ppc mac' => 'Power PC Mac', 'freebsd' => 'FreeBSD', 'ppc' => 'Macintosh', 'linux' => 'Linux', 'debian' => 'Debian', 'sunos' => 'Sun Solaris', 'beos' => 'BeOS', 'apachebench' => 'ApacheBench', 'aix' => 'AIX', 'irix' => 'Irix', 'osf' => 'DEC OSF', 'hp-ux' => 'HP-UX', 'netbsd' => 'NetBSD', 'bsdi' => 'BSDi', 'openbsd' => 'OpenBSD', 'gnu' => 'GNU/Linux', 'unix' => 'Unknown Unix OS', 'symbian' => 'Symbian OS' ); // The order of this array should NOT be changed. Many browsers return // multiple browser types so we want to identify the sub-type first. $browsers = array( 'OPR' => 'Opera', 'Flock' => 'Flock', 'Edge' => 'Edge', 'Chrome' => 'Chrome', // Opera 10+ always reports Opera/9.80 and appends Version/Directory access is forbidden.
================================================ FILE: application/core/index.html ================================================Directory access is forbidden.
================================================ FILE: application/helpers/index.html ================================================Directory access is forbidden.
================================================ FILE: application/hooks/index.html ================================================Directory access is forbidden.
================================================ FILE: application/index.html ================================================Directory access is forbidden.
================================================ FILE: application/language/english/index.html ================================================Directory access is forbidden.
================================================ FILE: application/language/index.html ================================================Directory access is forbidden.
================================================ FILE: application/libraries/index.html ================================================Directory access is forbidden.
================================================ FILE: application/logs/index.html ================================================Directory access is forbidden.
================================================ FILE: application/models/index.html ================================================Directory access is forbidden.
================================================ FILE: application/third_party/index.html ================================================Directory access is forbidden.
================================================ FILE: application/views/errors/cli/error_404.php ================================================ An uncaught Exception was encountered Type: Message: Filename: getFile(), "\n"; ?> Line Number: getLine(); ?> Backtrace: getTrace() as $error): ?> File: Line: Function: ================================================ FILE: application/views/errors/cli/error_general.php ================================================ A PHP Error was encountered Severity: Message: Filename: Line Number: Backtrace: File: Line: Function: ================================================ FILE: application/views/errors/cli/index.html ================================================Directory access is forbidden.
================================================ FILE: application/views/errors/html/error_404.php ================================================Type:
Message:
Filename: getFile(); ?>
Line Number: getLine(); ?>
Backtrace:
getTrace() as $error): ?>
File:
Line:
Function:
Severity:
Message:
Filename:
Line Number:
Backtrace:
File:
Line:
Function:
Directory access is forbidden.
================================================ FILE: application/views/errors/index.html ================================================Directory access is forbidden.
================================================ FILE: application/views/index.html ================================================Directory access is forbidden.
================================================ FILE: application/views/welcome_message.php ================================================The page you are looking at is being generated dynamically by CodeIgniter.
If you would like to edit this page you'll find it located at:
application/views/welcome_message.php
The corresponding controller for this page is found at:
application/controllers/Welcome.php
If you are exploring CodeIgniter for the very first time, you should start by reading the User Guide.
'.(is_array($message) ? implode('
', $message) : $message).'
'; $template = 'html'.DIRECTORY_SEPARATOR.$template; } if (ob_get_level() > $this->ob_level + 1) { ob_end_flush(); } ob_start(); include($templates_path.$template.'.php'); $buffer = ob_get_contents(); ob_end_clean(); return $buffer; } // -------------------------------------------------------------------- public function show_exception($exception) { $templates_path = config_item('error_views_path'); if (empty($templates_path)) { $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR; } else { $templates_path = rtrim($templates_path, '/\\').DIRECTORY_SEPARATOR; } $message = $exception->getMessage(); if (empty($message)) { $message = '(null)'; } if (is_cli()) { $templates_path .= 'cli'.DIRECTORY_SEPARATOR; } else { $templates_path .= 'html'.DIRECTORY_SEPARATOR; } if (ob_get_level() > $this->ob_level + 1) { ob_end_flush(); } ob_start(); include($templates_path.'error_exception.php'); $buffer = ob_get_contents(); ob_end_clean(); echo $buffer; } // -------------------------------------------------------------------- /** * Native PHP error handler * * @param int $severity Error level * @param string $message Error message * @param string $filepath File path * @param int $line Line number * @return void */ public function show_php_error($severity, $message, $filepath, $line) { $templates_path = config_item('error_views_path'); if (empty($templates_path)) { $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR; } else { $templates_path = rtrim($templates_path, '/\\').DIRECTORY_SEPARATOR; } $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity; // For safety reasons we don't show the full file path in non-CLI requests if ( ! is_cli()) { $filepath = str_replace('\\', '/', $filepath); if (FALSE !== strpos($filepath, '/')) { $x = explode('/', $filepath); $filepath = $x[count($x)-2].'/'.end($x); } $template = 'html'.DIRECTORY_SEPARATOR.'error_php'; } else { $template = 'cli'.DIRECTORY_SEPARATOR.'error_php'; } if (ob_get_level() > $this->ob_level + 1) { ob_end_flush(); } ob_start(); include($templates_path.$template.'.php'); $buffer = ob_get_contents(); ob_end_clean(); echo $buffer; } } ================================================ FILE: system/core/Hooks.php ================================================ item('enable_hooks') === FALSE) { return; } // Grab the "hooks" definition file. if (file_exists(APPPATH.'config/hooks.php')) { include(APPPATH.'config/hooks.php'); } if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php')) { include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'); } // If there are no hooks, we're done. if ( ! isset($hook) OR ! is_array($hook)) { return; } $this->hooks =& $hook; $this->enabled = TRUE; } // -------------------------------------------------------------------- /** * Call Hook * * Calls a particular hook. Called by CodeIgniter.php. * * @uses CI_Hooks::_run_hook() * * @param string $which Hook name * @return bool TRUE on success or FALSE on failure */ public function call_hook($which = '') { if ( ! $this->enabled OR ! isset($this->hooks[$which])) { return FALSE; } if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function'])) { foreach ($this->hooks[$which] as $val) { $this->_run_hook($val); } } else { $this->_run_hook($this->hooks[$which]); } return TRUE; } // -------------------------------------------------------------------- /** * Run Hook * * Runs a particular hook * * @param array $data Hook details * @return bool TRUE on success or FALSE on failure */ protected function _run_hook($data) { // Closures/lambda functions and array($object, 'method') callables if (is_callable($data)) { is_array($data) ? $data[0]->{$data[1]}() : $data(); return TRUE; } elseif ( ! is_array($data)) { return FALSE; } // ----------------------------------- // Safety - Prevents run-away loops // ----------------------------------- // If the script being called happens to have the same // hook call within it a loop can happen if ($this->_in_progress === TRUE) { return; } // ----------------------------------- // Set file path // ----------------------------------- if ( ! isset($data['filepath'], $data['filename'])) { return FALSE; } $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; if ( ! file_exists($filepath)) { return FALSE; } // Determine and class and/or function names $class = empty($data['class']) ? FALSE : $data['class']; $function = empty($data['function']) ? FALSE : $data['function']; $params = isset($data['params']) ? $data['params'] : ''; if (empty($function)) { return FALSE; } // Set the _in_progress flag $this->_in_progress = TRUE; // Call the requested class and/or function if ($class !== FALSE) { // The object is stored? if (isset($this->_objects[$class])) { if (method_exists($this->_objects[$class], $function)) { $this->_objects[$class]->$function($params); } else { return $this->_in_progress = FALSE; } } else { class_exists($class, FALSE) OR require_once($filepath); if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function)) { return $this->_in_progress = FALSE; } // Store the object and execute the method $this->_objects[$class] = new $class(); $this->_objects[$class]->$function($params); } } else { function_exists($function) OR require_once($filepath); if ( ! function_exists($function)) { return $this->_in_progress = FALSE; } $function($params); } $this->_in_progress = FALSE; return TRUE; } } ================================================ FILE: system/core/Input.php ================================================ security = $security; log_message('info', 'Input Class Initialized'); } // -------------------------------------------------------------------- /** * Fetch from array * * Internal method used to retrieve values from global arrays. * * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc. * @param mixed $index Index for item to be fetched from $array * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = FALSE) { // If $index is NULL, it means that the whole $array is requested isset($index) OR $index = array_keys($array); // allow fetching multiple keys at once if (is_array($index)) { $output = array(); foreach ($index as $key) { $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean); } return $output; } if (isset($array[$index])) { $value = $array[$index]; } elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation { $value = $array; for ($i = 0; $i < $count; $i++) { $key = trim($matches[0][$i], '[]'); if ($key === '') // Empty notation will return the value as array { break; } if (isset($value[$key])) { $value = $value[$key]; } else { return NULL; } } } else { return NULL; } return ($xss_clean === TRUE) ? $this->security->xss_clean($value) : $value; } // -------------------------------------------------------------------- /** * Fetch an item from the GET array * * @param mixed $index Index for item to be fetched from $_GET * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function get($index = NULL, $xss_clean = FALSE) { return $this->_fetch_from_array($_GET, $index, $xss_clean); } // -------------------------------------------------------------------- /** * Fetch an item from the POST array * * @param mixed $index Index for item to be fetched from $_POST * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function post($index = NULL, $xss_clean = FALSE) { return $this->_fetch_from_array($_POST, $index, $xss_clean); } // -------------------------------------------------------------------- /** * Fetch an item from POST data with fallback to GET * * @param string $index Index for item to be fetched from $_POST or $_GET * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function post_get($index, $xss_clean = FALSE) { $output = $this->post($index, $xss_clean); return isset($output) ? $output : $this->get($index, $xss_clean); } // -------------------------------------------------------------------- /** * Fetch an item from GET data with fallback to POST * * @param string $index Index for item to be fetched from $_GET or $_POST * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function get_post($index, $xss_clean = FALSE) { $output = $this->get($index, $xss_clean); return isset($output) ? $output : $this->post($index, $xss_clean); } // -------------------------------------------------------------------- /** * Fetch an item from the COOKIE array * * @param mixed $index Index for item to be fetched from $_COOKIE * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function cookie($index = NULL, $xss_clean = FALSE) { return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); } // -------------------------------------------------------------------- /** * Fetch an item from the SERVER array * * @param mixed $index Index for item to be fetched from $_SERVER * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function server($index, $xss_clean = FALSE) { return $this->_fetch_from_array($_SERVER, $index, $xss_clean); } // ------------------------------------------------------------------------ /** * Fetch an item from the php://input stream * * Useful when you need to access PUT, DELETE or PATCH request data. * * @param string $index Index for item to be fetched * @param bool $xss_clean Whether to apply XSS filtering * @return mixed */ public function input_stream($index = NULL, $xss_clean = FALSE) { // Prior to PHP 5.6, the input stream can only be read once, // so we'll need to check if we have already done that first. if ( ! is_array($this->_input_stream)) { // $this->raw_input_stream will trigger __get(). parse_str($this->raw_input_stream, $this->_input_stream); is_array($this->_input_stream) OR $this->_input_stream = array(); } return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); } // ------------------------------------------------------------------------ /** * Set cookie * * Accepts an arbitrary number of parameters (up to 7) or an associative * array in the first parameter containing all the values. * * @param string|mixed[] $name Cookie name or an array containing parameters * @param string $value Cookie value * @param int $expire Cookie expiration time in seconds * @param string $domain Cookie domain (e.g.: '.yourdomain.com') * @param string $path Cookie path (default: '/') * @param string $prefix Cookie name prefix * @param bool $secure Whether to only transfer cookies via SSL * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript) * @param string $samesite SameSite attribute * @return void */ public function set_cookie($name, $value = '', $expire = 0, $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL, $samesite = NULL) { if (is_array($name)) { // always leave 'name' in last place, as the loop will break otherwise, due to $$item foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'samesite', 'name') as $item) { if (isset($name[$item])) { $$item = $name[$item]; } } } if ($prefix === '' && config_item('cookie_prefix') !== '') { $prefix = config_item('cookie_prefix'); } if ($domain == '' && config_item('cookie_domain') != '') { $domain = config_item('cookie_domain'); } if ($path === '/' && config_item('cookie_path') !== '/') { $path = config_item('cookie_path'); } $secure = ($secure === NULL && config_item('cookie_secure') !== NULL) ? (bool) config_item('cookie_secure') : (bool) $secure; $httponly = ($httponly === NULL && config_item('cookie_httponly') !== NULL) ? (bool) config_item('cookie_httponly') : (bool) $httponly; if ( ! is_numeric($expire) OR $expire < 0) { $expire = 1; } else { $expire = ($expire > 0) ? time() + $expire : 0; } isset($samesite) OR $samesite = config_item('cookie_samesite'); if (isset($samesite)) { $samesite = ucfirst(strtolower($samesite)); in_array($samesite, array('Lax', 'Strict', 'None'), TRUE) OR $samesite = 'Lax'; } else { $samesite = 'Lax'; } if ($samesite === 'None' && ! $secure) { log_message('error', $name.' cookie sent with SameSite=None, but without Secure attribute.'); } if ( ! is_php('7.3')) { $maxage = $expire - time(); if ($maxage < 1) { $maxage = 0; } $cookie_header = 'Set-Cookie: '.$prefix.$name.'='.rawurlencode($value); $cookie_header .= ($expire === 0 ? '' : '; Expires='.gmdate('D, d-M-Y H:i:s T', $expire)).'; Max-Age='.$maxage; $cookie_header .= '; Path='.$path.($domain !== '' ? '; Domain='.$domain : ''); $cookie_header .= ($secure ? '; Secure' : '').($httponly ? '; HttpOnly' : '').'; SameSite='.$samesite; header($cookie_header); return; } $setcookie_options = array( 'expires' => $expire, 'path' => $path, 'domain' => $domain, 'secure' => $secure, 'httponly' => $httponly, 'samesite' => $samesite, ); setcookie($prefix.$name, $value, $setcookie_options); } // -------------------------------------------------------------------- /** * Fetch the IP Address * * Determines and validates the visitor's IP address. * * @return string IP address */ public function ip_address() { if ($this->ip_address !== FALSE) { return $this->ip_address; } $proxy_ips = config_item('proxy_ips'); if ( ! empty($proxy_ips) && ! is_array($proxy_ips)) { $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips)); } $this->ip_address = $this->server('REMOTE_ADDR'); if ($proxy_ips) { foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header) { if (($spoof = $this->server($header)) !== NULL) { // Some proxies typically list the whole chain of IP // addresses through which the client has reached us. // e.g. client_ip, proxy_ip1, proxy_ip2, etc. sscanf($spoof, '%[^,]', $spoof); if ( ! $this->valid_ip($spoof)) { $spoof = NULL; } else { break; } } } if ($spoof) { for ($i = 0, $c = count($proxy_ips); $i < $c; $i++) { // Check if we have an IP address or a subnet if (strpos($proxy_ips[$i], '/') === FALSE) { // An IP address (and not a subnet) is specified. // We can compare right away. if ($proxy_ips[$i] === $this->ip_address) { $this->ip_address = $spoof; break; } continue; } // We have a subnet ... now the heavy lifting begins isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.'; // If the proxy entry doesn't match the IP protocol - skip it if (strpos($proxy_ips[$i], $separator) === FALSE) { continue; } // Convert the REMOTE_ADDR IP address to binary, if needed if ( ! isset($ip, $sprintf)) { if ($separator === ':') { // Make sure we're have the "full" IPv6 format $ip = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($this->ip_address, ':')), $this->ip_address ) ); for ($j = 0; $j < 8; $j++) { $ip[$j] = intval($ip[$j], 16); } $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b'; } else { $ip = explode('.', $this->ip_address); $sprintf = '%08b%08b%08b%08b'; } $ip = vsprintf($sprintf, $ip); } // Split the netmask length off the network address sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen); // Again, an IPv6 address is most likely in a compressed form if ($separator === ':') { $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); for ($j = 0; $j < 8; $j++) { $netaddr[$j] = intval($netaddr[$j], 16); } } else { $netaddr = explode('.', $netaddr); } // Convert to binary and finally compare if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) { $this->ip_address = $spoof; break; } } } } if ( ! $this->valid_ip($this->ip_address)) { return $this->ip_address = '0.0.0.0'; } return $this->ip_address; } // -------------------------------------------------------------------- /** * Validate IP Address * * @param string $ip IP address * @param string $which IP protocol: 'ipv4' or 'ipv6' * @return bool */ public function valid_ip($ip, $which = '') { switch (strtolower($which)) { case 'ipv4': $which = FILTER_FLAG_IPV4; break; case 'ipv6': $which = FILTER_FLAG_IPV6; break; default: $which = 0; break; } return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which); } // -------------------------------------------------------------------- /** * Fetch User Agent string * * @return string|null User Agent string or NULL if it doesn't exist */ public function user_agent($xss_clean = FALSE) { return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean); } // -------------------------------------------------------------------- /** * Request Headers * * @param bool $xss_clean Whether to apply XSS filtering * @return array */ public function request_headers($xss_clean = FALSE) { // If header is already defined, return it immediately if ( ! empty($this->headers)) { return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // In Apache, you can simply call apache_request_headers() if (function_exists('apache_request_headers')) { $this->headers = apache_request_headers(); } else { isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE']; foreach ($_SERVER as $key => $val) { if (sscanf($key, 'HTTP_%s', $header) === 1) { // take SOME_HEADER and turn it into Some-Header $header = str_replace('_', ' ', strtolower($header)); $header = str_replace(' ', '-', ucwords($header)); $this->headers[$header] = $_SERVER[$key]; } } } return $this->_fetch_from_array($this->headers, NULL, $xss_clean); } // -------------------------------------------------------------------- /** * Get Request Header * * Returns the value of a single member of the headers class member * * @param string $index Header name * @param bool $xss_clean Whether to apply XSS filtering * @return string|null The requested header on success or NULL on failure */ public function get_request_header($index, $xss_clean = FALSE) { static $headers; if ( ! isset($headers)) { empty($this->headers) && $this->request_headers(); foreach ($this->headers as $key => $value) { $headers[strtolower($key)] = $value; } } $index = strtolower($index); if ( ! isset($headers[$index])) { return NULL; } return ($xss_clean === TRUE) ? $this->security->xss_clean($headers[$index]) : $headers[$index]; } // -------------------------------------------------------------------- /** * Is AJAX request? * * Test to see if a request contains the HTTP_X_REQUESTED_WITH header. * * @return bool */ public function is_ajax_request() { return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); } // -------------------------------------------------------------------- /** * Get Request Method * * Return the request method * * @param bool $upper Whether to return in upper or lower case * (default: FALSE) * @return string */ public function method($upper = FALSE) { return ($upper) ? strtoupper($this->server('REQUEST_METHOD')) : strtolower($this->server('REQUEST_METHOD')); } // ------------------------------------------------------------------------ /** * Magic __get() * * Allows read access to protected properties * * @param string $name * @return mixed */ public function __get($name) { if ($name === 'raw_input_stream') { isset($this->_raw_input_stream) OR $this->_raw_input_stream = file_get_contents('php://input'); return $this->_raw_input_stream; } elseif ($name === 'ip_address') { return $this->ip_address; } } } ================================================ FILE: system/core/Lang.php ================================================ load($value, $idiom, $return, $add_suffix, $alt_path); } return; } $langfile = str_replace('.php', '', $langfile); if ($add_suffix === TRUE) { $langfile = preg_replace('/_lang$/', '', $langfile).'_lang'; } $langfile .= '.php'; if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom)) { $config =& get_config(); $idiom = empty($config['language']) ? 'english' : $config['language']; } if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom) { return; } // Load the base file, so any others found can override it $basepath = BASEPATH.'language/'.$idiom.'/'.$langfile; if (($found = file_exists($basepath)) === TRUE) { include($basepath); } // Do we have an alternative path to look in? if ($alt_path !== '') { $alt_path .= 'language/'.$idiom.'/'.$langfile; if (file_exists($alt_path)) { include($alt_path); $found = TRUE; } } else { foreach (get_instance()->load->get_package_paths(TRUE) as $package_path) { $package_path .= 'language/'.$idiom.'/'.$langfile; if ($basepath !== $package_path && file_exists($package_path)) { include($package_path); $found = TRUE; break; } } } if ($found !== TRUE) { show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile); } if ( ! isset($lang) OR ! is_array($lang)) { log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile); if ($return === TRUE) { return array(); } return; } if ($return === TRUE) { return $lang; } $this->is_loaded[$langfile] = $idiom; $this->language = array_merge($this->language, $lang); log_message('info', 'Language file loaded: language/'.$idiom.'/'.$langfile); return TRUE; } // -------------------------------------------------------------------- /** * Language line * * Fetches a single line of text from the language array * * @param string $line Language line key * @param bool $log_errors Whether to log an error message if the line is not found * @return string Translation */ public function line($line, $log_errors = TRUE) { $value = isset($this->language[$line]) ? $this->language[$line] : FALSE; // Because killer robots like unicorns! if ($value === FALSE && $log_errors === TRUE) { log_message('error', 'Could not find the language line "'.$line.'"'); } return $value; } } ================================================ FILE: system/core/Loader.php ================================================ 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(); /** * Stack of variable arrays to provide nested _ci_load calls with all variables from parent calls * * @var array */ protected $_ci_load_vars_stack = 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); } } if ( ! is_subclass_of($model, 'CI_Model')) { throw new RuntimeException("Class ".$model." 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 * @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) { // Grab the super object $CI =& get_instance(); // Do we even need to load the database class? if ($return === FALSE && 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); } // Initialize the db variable. Needed to prevent // reference errors with some configurations $CI->db = ''; // Load the DB class $CI->db =& DB($params); 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 stack 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 so that loaded views and files have access to these * variables. * Additionally we want all subsequent nested _ci_load() calls embedded * within the current file to 'inherit' all variables that are * accessible to the current file. For this purpose we push the current * variable configuration (_ci_vars) to the stack and remove it again * after the file or view is completely loaded. Nested _ci_load() calls * within the current file extend the stack with their variable * configuration. */ is_array($_ci_vars) OR $_ci_vars = array(); // Include the global cached vars into the current _ci_vars if needed empty($this->_ci_cached_vars) OR $_ci_vars = array_merge($this->_ci_cached_vars, $_ci_vars); // Merge the last variable configuration from a parent _ci_load() // call into the current _ci_vars if ( ! empty($this->_ci_load_vars_stack)) { $previous_variable_configuration = end($this->_ci_load_vars_stack); $_ci_vars = array_merge($previous_variable_configuration, $_ci_vars); } array_push($this->_ci_load_vars_stack, $_ci_vars); extract($_ci_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(); include($_ci_path); // include() vs include_once() allows for multiple views with the same name log_message('info', 'File loaded: '.$_ci_path); // Remove current _ci_vars from stack array_pop($this->_ci_load_vars_stack); // Return the file data if requested if ($_ci_return === TRUE) { $buffer = ob_get_contents(); @ob_end_clean(); return $buffer; } /* * Flush the buffer... or buff the flusher? * * In order to permit views to be nested within * other views, we need to flush the content back out whenever * we are beyond the first level of output buffering so that * it can be seen and included properly by the first included * template and any subsequent ones. Oy! */ if (ob_get_level() > $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; } } ================================================ FILE: system/core/Log.php ================================================ 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4); /** * mbstring.func_overload flag * * @var bool */ protected static $func_overload; // -------------------------------------------------------------------- /** * Class constructor * * @return void */ public function __construct() { $config =& get_config(); isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); $this->_log_path = ($config['log_path'] !== '') ? rtrim($config['log_path'], '/\\').DIRECTORY_SEPARATOR : APPPATH.'logs'.DIRECTORY_SEPARATOR; $this->_log_filename = (isset($config['log_filename']) && $config['log_filename'] !== '') ? $config['log_filename'] : 'log-'.date('Y-m-d').'.php'; file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE); if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path)) { $this->_enabled = FALSE; } if (is_numeric($config['log_threshold'])) { $this->_threshold = (int) $config['log_threshold']; } elseif (is_array($config['log_threshold'])) { $this->_threshold = 0; $this->_threshold_array = array_flip($config['log_threshold']); } if ( ! empty($config['log_date_format'])) { $this->_date_fmt = $config['log_date_format']; } if ( ! empty($config['log_file_permissions']) && is_int($config['log_file_permissions'])) { $this->_file_permissions = $config['log_file_permissions']; } } // -------------------------------------------------------------------- /** * Write Log File * * Generally this function will be called using the global log_message() function * * @param string $level The error level: 'error', 'debug' or 'info' * @param string $msg The error message * @return bool */ public function write_log($level, $msg) { if ($this->_enabled === FALSE) { return FALSE; } $level = strtoupper($level); if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) && ! isset($this->_threshold_array[$this->_levels[$level]])) { return FALSE; } $filepath = $this->_log_path.$this->_log_filename; $message = ''; if ( ! file_exists($filepath)) { $newfile = TRUE; // Only add protection to php files if (substr($this->_log_filename, -3, 3) === 'php') { $message .= "\n\n"; } } if ( ! $fp = @fopen($filepath, 'ab')) { return FALSE; } flock($fp, LOCK_EX); // Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format if (strpos($this->_date_fmt, 'u') !== FALSE) { $microtime_full = microtime(TRUE); $microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000); $date = new DateTime(date('Y-m-d H:i:s.'.$microtime_short, $microtime_full)); $date = $date->format($this->_date_fmt); } else { $date = date($this->_date_fmt); } $message .= $this->_format_line($level, $date, $msg); for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result) { if (($result = fwrite($fp, self::substr($message, $written))) === FALSE) { break; } } flock($fp, LOCK_UN); fclose($fp); if (isset($newfile) && $newfile === TRUE) { chmod($filepath, $this->_file_permissions); } return is_int($result); } // -------------------------------------------------------------------- /** * Format the log line. * * This is for extensibility of log formatting * If you want to change the log format, extend the CI_Log class and override this method * * @param string $level The error level * @param string $date Formatted date string * @param string $message The log message * @return string Formatted log line with a new line character at the end */ protected function _format_line($level, $date, $message) { return $level.' - '.$date.' --> '.$message.PHP_EOL; } // -------------------------------------------------------------------- /** * Byte-safe strlen() * * @param string $str * @return int */ protected static function strlen($str) { return (self::$func_overload) ? mb_strlen($str, '8bit') : strlen($str); } // -------------------------------------------------------------------- /** * Byte-safe substr() * * @param string $str * @param int $start * @param int $length * @return string */ protected static function substr($str, $start, $length = NULL) { if (self::$func_overload) { return mb_substr($str, $start, $length, '8bit'); } return isset($length) ? substr($str, $start, $length) : substr($str, $start); } } ================================================ FILE: system/core/Model.php ================================================ $key; } } ================================================ FILE: system/core/Output.php ================================================ _zlib_oc = (bool) ini_get('zlib.output_compression'); $this->_compress_output = ( $this->_zlib_oc === FALSE && config_item('compress_output') === TRUE && extension_loaded('zlib') ); isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); // Get mime types for later $this->mimes =& get_mimes(); log_message('info', 'Output Class Initialized'); } // -------------------------------------------------------------------- /** * Get Output * * Returns the current output string. * * @return string */ public function get_output() { return $this->final_output; } // -------------------------------------------------------------------- /** * Set Output * * Sets the output string. * * @param string $output Output data * @return CI_Output */ public function set_output($output) { $this->final_output = $output; return $this; } // -------------------------------------------------------------------- /** * Append Output * * Appends data onto the output string. * * @param string $output Data to append * @return CI_Output */ public function append_output($output) { $this->final_output .= $output; return $this; } // -------------------------------------------------------------------- /** * Set Header * * Lets you set a server header which will be sent with the final output. * * Note: If a file is cached, headers will not be sent. * @todo We need to figure out how to permit headers to be cached. * * @param string $header Header * @param bool $replace Whether to replace the old header value, if already set * @return CI_Output */ public function set_header($header, $replace = TRUE) { // If zlib.output_compression is enabled it will compress the output, // but it will not modify the content-length header to compensate for // the reduction, causing the browser to hang waiting for more data. // We'll just skip content-length in those cases. if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0) { return $this; } $this->headers[] = array($header, $replace); return $this; } // -------------------------------------------------------------------- /** * Set Content-Type Header * * @param string $mime_type Extension of the file we're outputting * @param string $charset Character set (default: NULL) * @return CI_Output */ public function set_content_type($mime_type, $charset = NULL) { if (strpos($mime_type, '/') === FALSE) { $extension = ltrim($mime_type, '.'); // Is this extension supported? if (isset($this->mimes[$extension])) { $mime_type =& $this->mimes[$extension]; if (is_array($mime_type)) { $mime_type = current($mime_type); } } } $this->mime_type = $mime_type; if (empty($charset)) { $charset = config_item('charset'); } $header = 'Content-Type: '.$mime_type .(empty($charset) ? '' : '; charset='.$charset); $this->headers[] = array($header, TRUE); return $this; } // -------------------------------------------------------------------- /** * Get Current Content-Type Header * * @return string 'text/html', if not already set */ public function get_content_type() { for ($i = 0, $c = count($this->headers); $i < $c; $i++) { if (sscanf($this->headers[$i][0], 'Content-Type: %[^;]', $content_type) === 1) { return $content_type; } } return 'text/html'; } // -------------------------------------------------------------------- /** * Get Header * * @param string $header * @return string */ public function get_header($header) { // We only need [x][0] from our multi-dimensional array $header_lines = array_map(function ($headers) { return array_shift($headers); }, $this->headers); $headers = array_merge( $header_lines, headers_list() ); if (empty($headers) OR empty($header)) { return NULL; } // Count backwards, in order to get the last matching header for ($c = count($headers) - 1; $c > -1; $c--) { if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0) { return trim(self::substr($headers[$c], $l+1)); } } return NULL; } // -------------------------------------------------------------------- /** * Set HTTP Status Header * * As of version 1.7.2, this is an alias for common function * set_status_header(). * * @param int $code Status code (default: 200) * @param string $text Optional message * @return CI_Output */ public function set_status_header($code = 200, $text = '') { set_status_header($code, $text); return $this; } // -------------------------------------------------------------------- /** * Enable/disable Profiler * * @param bool $val TRUE to enable or FALSE to disable * @return CI_Output */ public function enable_profiler($val = TRUE) { $this->enable_profiler = is_bool($val) ? $val : TRUE; return $this; } // -------------------------------------------------------------------- /** * Set Profiler Sections * * Allows override of default/config settings for * Profiler section display. * * @param array $sections Profiler sections * @return CI_Output */ public function set_profiler_sections($sections) { if (isset($sections['query_toggle_count'])) { $this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count']; unset($sections['query_toggle_count']); } foreach ($sections as $section => $enable) { $this->_profiler_sections[$section] = ($enable !== FALSE); } return $this; } // -------------------------------------------------------------------- /** * Set Cache * * @param int $time Cache expiration time in minutes * @return CI_Output */ public function cache($time) { $this->cache_expiration = is_numeric($time) ? $time : 0; return $this; } // -------------------------------------------------------------------- /** * Display Output * * Processes and sends finalized output data to the browser along * with any server headers and profile data. It also stops benchmark * timers so the page rendering speed and memory usage can be shown. * * Note: All "view" data is automatically put into $this->final_output * by controller class. * * @uses CI_Output::$final_output * @param string $output Output data override * @return void */ public function _display($output = NULL) { // Note: We use load_class() because we can't use $CI =& get_instance() // since this function is sometimes called by the caching mechanism, // which happens before the CI super object is available. $BM =& load_class('Benchmark', 'core'); $CFG =& load_class('Config', 'core'); // Grab the super object if we can. if (class_exists('CI_Controller', FALSE)) { $CI =& get_instance(); } // -------------------------------------------------------------------- // Set the output data if ($output === NULL) { $output =& $this->final_output; } // -------------------------------------------------------------------- // Do we need to write a cache file? Only if the controller does not have its // own _output() method and we are not dealing with a cache file, which we // can determine by the existence of the $CI object above if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output')) { $this->_write_cache($output); } // -------------------------------------------------------------------- // Parse out the elapsed time and memory usage, // then swap the pseudo-variables with the data $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end'); if ($this->parse_exec_vars === TRUE) { $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB'; $output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output); } // -------------------------------------------------------------------- // Is compression requested? if (isset($CI) // This means that we're not serving a cache file, if we were, it would already be compressed && $this->_compress_output === TRUE && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { ob_start('ob_gzhandler'); } // -------------------------------------------------------------------- // Are there any server headers to send? if (count($this->headers) > 0) { foreach ($this->headers as $header) { @header($header[0], $header[1]); } } // -------------------------------------------------------------------- // Does the $CI object exist? // If not we know we are dealing with a cache file so we'll // simply echo out the data and exit. if ( ! isset($CI)) { if ($this->_compress_output === TRUE) { if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) { header('Content-Encoding: gzip'); header('Content-Length: '.self::strlen($output)); } else { // User agent doesn't support gzip compression, // so we'll have to decompress our cache $output = gzinflate(self::substr($output, 10, -8)); } } echo $output; log_message('info', 'Final output sent to browser'); log_message('info', 'Total execution time: '.$elapsed); return; } // -------------------------------------------------------------------- // Do we need to generate profile data? // If so, load the Profile class and run it. if ($this->enable_profiler === TRUE) { $CI->load->library('profiler'); if ( ! empty($this->_profiler_sections)) { $CI->profiler->set_sections($this->_profiler_sections); } // If the output data contains closing