Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 47 additions & 6 deletions .github/workflows/test-phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,28 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.3', '8.2', '8.1', '8.0', '7.4']
php: ['8.5', '8.4', '8.3', '8.2', '8.1', '8.0', '7.4']
DB: [ 'pdo/mysql', 'pdo/pgsql', 'pdo/sqlite', 'mysqli', 'pgsql', 'sqlite' ]
compiler: [ default ]
include:
- php: '8.5'
DB: 'pdo/mysql'
compiler: jit
- php: '8.5'
DB: 'pdo/pgsql'
compiler: jit
- php: '8.5'
DB: 'pdo/sqlite'
compiler: jit
- php: '8.5'
DB: 'mysqli'
compiler: jit
- php: '8.5'
DB: 'pgsql'
compiler: jit
- php: '8.5'
DB: 'sqlite'
compiler: jit
- php: '8.4'
DB: 'pdo/mysql'
compiler: jit
Expand Down Expand Up @@ -143,7 +161,7 @@ jobs:
tools: composer, pecl
extensions: imagick, sqlite3, pgsql, mysqli, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, mbstring
ini-values: ${{ env.PHP_INI_VALUES }}
coverage: xdebug
coverage: pcov # CHANGED from 'xdebug' to 'pcov'

- name: Get composer cache directory
id: composer-cache
Expand All @@ -153,12 +171,35 @@ jobs:
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
restore-keys: ${{ runner.os }}-composer-

# --- CRUCIAL NEW STEP WITH CORRECT INDENTATION ---
- name: Conditionally Lock PHPUnit 9 for older PHP versions
if: matrix.php == '7.4' || matrix.php == '8.0'
# This command updates the dependency in composer.json/lock without installing.
run: composer require --dev --no-update "phpunit/phpunit:^9.0"

- name: Install composer dependencies
# This runs the actual install after the lock/update (if any)
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 vendor/bin/phpunit --coverage-text --configuration tests/travis/${{ matrix.DB }}.phpunit.xml
env:
XDEBUG_MODE: coverage
# 1. Determine the configuration file based on PHP version
# Use the _v9 config file for older PHPUnit versions (PHP 7.4 & 8.0)
if [ "${{ matrix.php }}" = "7.4" ] || [ "${{ matrix.php }}" = "8.0" ]; then
CONFIG_FILE="tests/travis/${{ matrix.DB }}.phpunit_v9.xml"
STRICT_FLAGS="" # V9 files handle strictness via XML attributes
else
# Use the modern config file for PHPUnit 10/11 (PHP 8.1+)
CONFIG_FILE="tests/travis/${{ matrix.DB }}.phpunit.xml"
# Explicitly add flags to force failure on PHP Warnings/Notices,
# as the XML schema doesn't allow the modern equivalent tags.
STRICT_FLAGS="--fail-on-warning --fail-on-notice"
fi

# 2. Execute PHPUnit with dynamic configuration and flags
php -d error_reporting=E_ALL -d zend.enable_gc=0 -d date.timezone=UTC vendor/bin/phpunit \
--coverage-text \
--configuration ${CONFIG_FILE} \
${STRICT_FLAGS}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ user_guide_src/cilexer/pycilexer.egg-info/*
*.sublime-project
/tests/tests/
/tests/results/
/tests/.phpunit.result.cache
/tests/travis/.phpunit.result.cache
5 changes: 0 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
"type": "project",
"homepage": "https://github.com/NielBuys/CodeIgniter",
"license": "MIT",
"config": {
"platform": {
"php": "7.4"
}
},
"support": {
"forum": "http://forum.codeigniter.com/",
"issues": "https://github.com/NielBuys/CodeIgniter/issues",
Expand Down
12 changes: 6 additions & 6 deletions contributing.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing to CodeIgniter
# Contributing to this Fork of CodeIgniter 3

CodeIgniter is a community driven project and accepts contributions of code and documentation from the community. These contributions are made in the form of Issues or [Pull Requests](http://help.github.com/send-pull-requests/) on the [CodeIgniter repository](https://github.com/bcit-ci/CodeIgniter) on GitHub.
CodeIgniter is a community driven project and accepts contributions of code and documentation from the community. These contributions are made in the form of Issues or Pull Requests on the [Fork of CodeIgniter 3 repository](https://github.com/NielBuys/CodeIgniter) on GitHub.

Issues are a quick way to point out a bug. If you find a bug or documentation error in CodeIgniter then please check a few things first:

Expand Down Expand Up @@ -28,7 +28,7 @@ If you change anything that requires a change to documentation then you will nee

### Compatibility

CodeIgniter recommends PHP 7.2 or newer to be used
This Fork of CodeIgniter 3 recommends PHP 7.4 or newer to be used

### Branching

Expand Down Expand Up @@ -64,7 +64,7 @@ Easy way GitHub allows in-line editing of files for making simple typo changes a
Hard way The best way to contribute is to "clone" your fork of CodeIgniter to your development area. That sounds like some jargon, but "forking" on GitHub means "making a copy of that repo to your account" and "cloning" means "copying that code to your environment so you can work on it".

1. [Set up Git](https://help.github.com/en/articles/set-up-git) (Windows, Mac & Linux)
2. Go to the [CodeIgniter repo](https://github.com/bcit-ci/CodeIgniter)
2. Go to the [Fork of CodeIgniter repo](https://github.com/NielBuys/CodeIgniter)
3. [Fork it](https://help.github.com/en/articles/fork-a-repo)
4. [Clone](https://help.github.com/en/articles/fetching-a-remote#clone) your forked CodeIgniter repo: git@github.com:<your-name>/CodeIgniter.git.
5. Checkout the "develop" branch. At this point you are ready to start making changes.
Expand All @@ -79,11 +79,11 @@ Once the Reactor Engineer handling your pull request is happy with it they will

### Keeping your fork up-to-date

Unlike systems like Subversion, Git can have multiple remotes. A remote is the name for a URL of a Git repository. By default your fork will have a remote named "origin" which points to your fork, but you can add another remote named "codeigniter" which points to `git://github.com/bcit-ci/CodeIgniter.git`. This is a read-only remote but you can pull from this develop branch to update your own.
Unlike systems like Subversion, Git can have multiple remotes. A remote is the name for a URL of a Git repository. By default your fork will have a remote named "origin" which points to your fork, but you can add another remote named "codeigniter" which points to `git://github.com/NielBuys/CodeIgniter.git`. This is a read-only remote but you can pull from this develop branch to update your own.

If you are using command-line you can do the following:

1. `git remote add codeigniter git://github.com/bcit-ci/CodeIgniter.git`
1. `git remote add codeigniter git://github.com/NielBuys/CodeIgniter.git`
2. `git pull codeigniter develop`
3. `git push origin develop`

Expand Down
8 changes: 3 additions & 5 deletions readme.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ https://github.com/NielBuys/CodeIgniter/releases
Server Requirements
*******************

PHP version 7.4 or newer (PHP 8.4 ready) is recommended.
PHP version 7.4 or newer (PHP 8.5 ready) is recommended.

************
Installation
************

CodeIgniter is installed in four steps:

1. npm install nielbuys/framework
1. composer require nielbuys/framework
2. Change "codeigniter/framework" to "nielbuys/framework" in the "composer.json" file.
3. Change in main "index.php" the following line from "$system_path = 'vendor/codeigniter/framework/system';" to "$system_path = 'vendor/nielbuys/framework/system';"
4. Then run composer update.
Expand Down Expand Up @@ -62,14 +62,12 @@ Resources
*********

- `User Guide <https://codeigniter.com/userguide3/>`_
- `Contributing Guide <https://github.com/bcit-ci/CodeIgniter/blob/develop/contributing.md>`_
- `Contributing Guide <https://github.com/NielBuys/CodeIgniter/blob/develop/contributing.md>`_
- `Language File Translations <https://github.com/bcit-ci/codeigniter3-translations>`_
- `Community Forums <http://forum.codeigniter.com/>`_
- `Community Wiki <https://github.com/bcit-ci/CodeIgniter/wiki>`_
- `Community Slack Channel <https://codeigniterchat.slack.com>`_

Report security issues to our `Security Panel <mailto:security@codeigniter.com>`_
or via our `page on HackerOne <https://hackerone.com/codeigniter>`_, thank you.

***************
Acknowledgement
Expand Down
1 change: 1 addition & 0 deletions system/core/Lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE
*/
public function line($line, $log_errors = TRUE)
{
$line = (string) $line;
$value = isset($this->language[$line]) ? $this->language[$line] : FALSE;

// Because killer robots like unicorns!
Expand Down
54 changes: 43 additions & 11 deletions system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,37 @@ public function __construct($params)
*/
public function db_connect($persistent = FALSE)
{
if (PHP_VERSION_ID >= 80400 && class_exists('\Pdo\Mysql')) {
$CONST_PREFIX = \Pdo\Mysql::class . '::';
$ATTR_INIT_COMMAND_NAME = $CONST_PREFIX . 'ATTR_INIT_COMMAND';
$ATTR_COMPRESS_NAME = $CONST_PREFIX . 'ATTR_COMPRESS';
$ATTR_SSL_KEY_NAME = $CONST_PREFIX . 'ATTR_SSL_KEY';
$ATTR_SSL_CERT_NAME = $CONST_PREFIX . 'ATTR_SSL_CERT';
$ATTR_SSL_CA_NAME = $CONST_PREFIX . 'ATTR_SSL_CA';
$ATTR_SSL_CAPATH_NAME = $CONST_PREFIX . 'ATTR_SSL_CAPATH';
$ATTR_SSL_CIPHER_NAME = $CONST_PREFIX . 'ATTR_SSL_CIPHER';
$ATTR_SSL_VERIFY_SERVER_CERT_NAME = $CONST_PREFIX . 'ATTR_SSL_VERIFY_SERVER_CERT';
} else {
$CONST_PREFIX = \PDO::class . '::';
$ATTR_INIT_COMMAND_NAME = $CONST_PREFIX . 'MYSQL_ATTR_INIT_COMMAND';
$ATTR_COMPRESS_NAME = $CONST_PREFIX . 'MYSQL_ATTR_COMPRESS';
$ATTR_SSL_KEY_NAME = $CONST_PREFIX . 'MYSQL_ATTR_SSL_KEY';
$ATTR_SSL_CERT_NAME = $CONST_PREFIX . 'MYSQL_ATTR_SSL_CERT';
$ATTR_SSL_CA_NAME = $CONST_PREFIX . 'MYSQL_ATTR_SSL_CA';
$ATTR_SSL_CAPATH_NAME = $CONST_PREFIX . 'MYSQL_ATTR_SSL_CAPATH';
$ATTR_SSL_CIPHER_NAME = $CONST_PREFIX . 'MYSQL_ATTR_SSL_CIPHER';
$ATTR_SSL_VERIFY_SERVER_CERT_NAME = $CONST_PREFIX . 'MYSQL_ATTR_SSL_VERIFY_SERVER_CERT';
}

$ATTR_INIT_COMMAND = constant($ATTR_INIT_COMMAND_NAME);
$ATTR_COMPRESS = constant($ATTR_COMPRESS_NAME);
$ATTR_SSL_KEY = constant($ATTR_SSL_KEY_NAME);
$ATTR_SSL_CERT = constant($ATTR_SSL_CERT_NAME);
$ATTR_SSL_CA = constant($ATTR_SSL_CA_NAME);
$ATTR_SSL_CAPATH = constant($ATTR_SSL_CAPATH_NAME);
$ATTR_SSL_CIPHER = constant($ATTR_SSL_CIPHER_NAME);
$ATTR_SSL_VERIFY_SERVER_CERT = constant($ATTR_SSL_VERIFY_SERVER_CERT_NAME) ?? -1;

if (isset($this->stricton))
{
if ($this->stricton)
Expand All @@ -143,34 +174,35 @@ public function db_connect($persistent = FALSE)

if ( ! empty($sql))
{
if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND]))
if (empty($this->options[$ATTR_INIT_COMMAND]))
{
$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode = '.$sql;
$this->options[$ATTR_INIT_COMMAND] = 'SET SESSION sql_mode = '.$sql;
}
else
{
$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = '.$sql;
$this->options[$ATTR_INIT_COMMAND] .= ', @@session.sql_mode = '.$sql;
}
}
}

if ($this->compress === TRUE)
{
$this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE;
$this->options[$ATTR_COMPRESS] = TRUE;
}

if (is_array($this->encrypt))
{
$ssl = array();
empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key'];
empty($this->encrypt['ssl_cert']) OR $ssl[PDO::MYSQL_ATTR_SSL_CERT] = $this->encrypt['ssl_cert'];
empty($this->encrypt['ssl_ca']) OR $ssl[PDO::MYSQL_ATTR_SSL_CA] = $this->encrypt['ssl_ca'];
empty($this->encrypt['ssl_capath']) OR $ssl[PDO::MYSQL_ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath'];
empty($this->encrypt['ssl_cipher']) OR $ssl[PDO::MYSQL_ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher'];
empty($this->encrypt['ssl_key']) OR $ssl[$ATTR_SSL_KEY] = $this->encrypt['ssl_key'];
empty($this->encrypt['ssl_cert']) OR $ssl[$ATTR_SSL_CERT] = $this->encrypt['ssl_cert'];
empty($this->encrypt['ssl_ca']) OR $ssl[$ATTR_SSL_CA] = $this->encrypt['ssl_ca'];
empty($this->encrypt['ssl_capath']) OR $ssl[$ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath'];
empty($this->encrypt['ssl_cipher']) OR $ssl[$ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher'];


if (defined('PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT') && isset($this->encrypt['ssl_verify']))
if ($ATTR_SSL_VERIFY_SERVER_CERT !== -1 && isset($this->encrypt['ssl_verify']))
{
$ssl[PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = $this->encrypt['ssl_verify'];
$ssl[$ATTR_SSL_VERIFY_SERVER_CERT] = $this->encrypt['ssl_verify'];
}

// DO NOT use array_merge() here!
Expand Down
4 changes: 3 additions & 1 deletion system/helpers/captcha_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,9 @@ function create_captcha($data = '', $img_path = '', $img_url = '', $font_path =
}

$img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_url.$img_filename.'" style="width: '.$img_width.'px; height: '.$img_height .'px; border: 0;" alt=" " />';
ImageDestroy($im);
if (PHP_VERSION_ID < 80500) {
ImageDestroy($im);
}

return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename);
}
Expand Down
26 changes: 18 additions & 8 deletions system/libraries/Image_lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -840,8 +840,10 @@ public function image_process_gd($action = 'resize')
}

// Kill the file handles
imagedestroy($dst_img);
imagedestroy($src_img);
if (PHP_VERSION_ID < 80500) {
imagedestroy($dst_img);
imagedestroy($src_img);
}

if ($this->dynamic_output !== TRUE)
{
Expand Down Expand Up @@ -1049,8 +1051,10 @@ public function image_rotate_gd()
}

// Kill the file handles
imagedestroy($dst_img);
imagedestroy($src_img);
if (PHP_VERSION_ID < 80500) {
imagedestroy($dst_img);
imagedestroy($src_img);
}

chmod($this->full_dst_path, $this->file_permissions);

Expand Down Expand Up @@ -1128,7 +1132,9 @@ public function image_mirror_gd()
}

// Kill the file handles
imagedestroy($src_img);
if (PHP_VERSION_ID < 80500) {
imagedestroy($src_img);
}

chmod($this->full_dst_path, $this->file_permissions);

Expand Down Expand Up @@ -1258,8 +1264,10 @@ public function overlay_watermark()
return FALSE;
}

imagedestroy($src_img);
imagedestroy($wm_img);
if (PHP_VERSION_ID < 80500) {
imagedestroy($src_img);
imagedestroy($wm_img);
}

return TRUE;
}
Expand Down Expand Up @@ -1429,7 +1437,9 @@ public function text_watermark()
$this->image_save_gd($src_img);
}

imagedestroy($src_img);
if (PHP_VERSION_ID < 80500) {
imagedestroy($src_img);
}

return TRUE;
}
Expand Down
4 changes: 3 additions & 1 deletion system/libraries/Upload.php
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,9 @@ protected function _file_mime_type($file)
if ($finfo !== FALSE) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
{
$mime = @finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (PHP_VERSION_ID < 80500) {
finfo_close($finfo);
}

/* According to the comments section of the PHP manual page,
* it is possible that this function returns an empty string
Expand Down
8 changes: 6 additions & 2 deletions system/libraries/Xmlrpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -1187,10 +1187,14 @@ public function parseResponse($fp)
xml_get_current_line_number($parser));

$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
xml_parser_free($parser);
if (PHP_VERSION_ID < 80500) {
xml_parser_free($parser);
}
return $r;
}
xml_parser_free($parser);
if (PHP_VERSION_ID < 80500) {
xml_parser_free($parser);
}

// Got ourselves some badness, it seems
if ($this->xh['isf'] > 1)
Expand Down
8 changes: 6 additions & 2 deletions system/libraries/Xmlrpcs.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,19 @@ public function parseRequest($data = '')
sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
xml_parser_free($parser);
if (PHP_VERSION_ID < 80500) {
xml_parser_free($parser);
}
}
elseif ($parser_object->xh['isf'])
{
return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
}
else
{
xml_parser_free($parser);
if (PHP_VERSION_ID < 80500) {
xml_parser_free($parser);
}

$m = new XML_RPC_Message($parser_object->xh['method']);
$plist = '';
Expand Down
Loading