Skip to content

Update to CodeIgniter 4.7.2#4485

Merged
objecttothis merged 18 commits into
masterfrom
codeigniter-472-upgrade
Apr 13, 2026
Merged

Update to CodeIgniter 4.7.2#4485
objecttothis merged 18 commits into
masterfrom
codeigniter-472-upgrade

Conversation

@objecttothis
Copy link
Copy Markdown
Member

@objecttothis objecttothis commented Apr 9, 2026

This Pull Request updates all necessary files to bring the application to CodeIgniter 4.7.2. 4.6.3 has known vulnerabilities, so this change must happen.

  • PHP 8.2 is now required for this project. Update existing Wiki, Readme and documentation to reflect this.
  • Upgrade 4.6.3 > 4.6.4
  • Upgrade 4.6.4 > 4.7.0
  • Upgrade 4.7.0 > 4.7.1
  • Upgrade 4.7.1 > 4.7.2
  • Merge Changes not previously merged
  • Create a GitHub Issue to look into and attempt to enable $CSPEnabled in app\Config\App now that all the keywords and directives are supported for CSP 3
  • Create a GitHub issue to add getters for all protected model variables since we are trying to access them directly and that isn't what should be done. Making them public is a bad idea because they can be modified in the code and that isn't good. They should be changed to private and add a getter then refactor calling code to use the getter.
  • Create a GitHub issue to deal with the duplicated code fragments. In many cases we should be refactoring out a function and calling that function anyway. Several of our Controller and model functions are way to large and this will help.
  • Create a GitHub issue to replace var with let or const depending on whether the value gets reassigned in all javascript as var should be avoided
  • Create a GitHub issue to correct the 4 functions in the Sales Controller that are missing return statements but the function has a return type.

Summary by CodeRabbit

  • New Features

    • WorkerMode config; APCu cache handler; Hostnames two-part TLD list; CSP reporting; SMTP auth option; view overrides folder; routing attribute toggle; migrations lock; encryption previous-keys.
  • Configuration Updates

    • Cache status-code filtering; shared connection options for requests; toolbar header-based disable list; JSON encode depth; env directory setting; session/worker-mode flags.
  • Breaking Changes

    • Minimum PHP requirement raised to 8.2; CSRF config now must be a string (no longer accepts false).
  • Improvements

    • Broader type hints; expanded bot detection; refined error UI and branding color; assorted view/JS/markup cleanups.

Signed-off-by: objec <objecttothis@gmail.com>
@coderabbitai

This comment was marked as resolved.

@objecttothis objecttothis changed the title Update Composer files for CodeIgniter 4.7.2 Update to CodeIgniter 4.7.2 Apr 9, 2026
- app\Config\Database.php
- app\Controllers\BaseController.php
- preload.php

Signed-off-by: objec <objecttothis@gmail.com>
@objecttothis objecttothis linked an issue Apr 9, 2026 that may be closed by this pull request
- Added app\Config\WorkerMode.php

Signed-off-by: objec <objecttothis@gmail.com>
- app\Config\App.php
- app\Config\Autoload.php
- app\Config\Cache.php
- app\Config\ContentSecurityPolicy.php
- app\Config\Cookie.php
- app\Config\CURLRequest.php
- app\Config\DocTypes.php
- app\Config\Email.php
- app\Config\Encryption.php
- app\Config\Filters.php
- app\Config\Format.php
- Added app\Config\Hostnames.php
- app\Config\Images.php
- app\Config\Logger.php
- app\Config\Migrations.php
- app\Config\Mimes.php
- app\Config\Modules.php
- app\Config\Optimize.php
- app\Config\Paths.php
- app\Config\Routing.php
- app\Config\Security.php

Signed-off-by: objec <objecttothis@gmail.com>
@jekkos
Copy link
Copy Markdown
Member

jekkos commented Apr 9, 2026

@objecttothis do squash the commits before merge. Btw if you like I can share an api key so you can use my ollama subscription. I was considering to swtich to github copilot next month as it offers more .models. The integration with github is better and you can then run agents fully in cloud wdyt

- app\Config\Session.php
- app\Config\Toolbar.php
- app\Config\UserAgents.php
- app\Config\View.php
- app\Config\Boot\testing.php
- public\resources\.gitkeep
- app\Views\errors\cli\error_exception.php
- app\Views\errors\html\debug.css
- app\Views\errors\html\error_400.php
- app\Views\errors\html\error_404.php
- app\Views\errors\html\error_exception.php

Signed-off-by: objec <objecttothis@gmail.com>
- Corrected incorrect CSS property used in invoice.php view.
- Corrected unknown CSS properties used in register.php view.
- Used shorthand CSS in debug.css
- Corrected indentation in barcode_sheet.php view.
- Corrected indentation in footer.php view.
- Corrected indentation in invoice_email.php view.
- Replaced obsolete attributes with CSS style attributes in barcode_sheet.php
- Replaced obsolete attribute in error_exception.php
- Replaced obsolete attribute in invoice_email.php
- Replaced obsolete attribute in quote_email.php
- Replaced obsolete attributes in work_order_email.php
- Fixed indentation in system_info.php
- Replaced <strong> tag outside <p> tags, which isn't allowed, with style attributes.
- Simplified js return logic and indentation fixes in tax_categories.php
- Simplified js return logic in tax_codes.php
- Simplified js return logic in tax_jurisdictions.php
- Removed unnecessary labels in manage views.
- Rewrite JavaScript function and PHP to be more readable in bar.php, hbar.php, line.php and pie.php
- Added type declarations, return types and an import to app\Config\Services
- Updated Attribute.php parameter type
- Updated Receiving_lib.php parameter type
- Updated Receivings.php parameter types and updated PHPdocs
- Updated tabular_helper.php parameter types and updated PHPdocs
- Added type declarations and corrected PHPdocs in url_helper.php
- Added return types to functions

Signed-off-by: objec <objecttothis@gmail.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/Config/Database.php (1)

130-132: ⚠️ Potential issue | 🟡 Minor

Syntax issue: semicolon instead of colon in switch case.

Line 130 uses a semicolon (;) instead of a colon (:) after 'development'. While PHP technically allows this (it's an alternative syntax), it's unconventional and may indicate a typo. Using a colon is the standard practice for switch cases.

🔧 Suggested fix
             case 'testing':
                 $this->defaultGroup = 'tests';
                 break;
-            case 'development';
+            case 'development':
                 $this->defaultGroup = 'development';
                 break;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Config/Database.php` around lines 130 - 132, In the switch block inside
the Database configuration (class Database / the switch that sets
$this->defaultGroup), replace the incorrect semicolon after the 'development'
case with the standard colon so the case reads case 'development': before
executing $this->defaultGroup = 'development'; and break; — this fixes the
unconventional/typo syntax and aligns the switch-case with normal PHP style.
app/Libraries/Receiving_lib.php (1)

395-401: ⚠️ Potential issue | 🟡 Minor

delete_item docs don’t match what the method actually deletes

Line 400 removes by cart line key ($items[$line]), but Line 395 documents $line as item_number/item_id. That mismatch can lead to non-deleting calls from future callers.

Suggested fix
-    /**
-     * `@param` $line int|string The item_number or item_id of the item to be removed from the receiving.
-     */
+    /**
+     * `@param` int|string $line Cart line key to remove from the receiving cart.
+     */
     public function delete_item(int|string $line): void
     {
         $items = $this->get_cart();
         unset($items[$line]);
         $this->set_cart($items);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Libraries/Receiving_lib.php` around lines 395 - 401, The docblock for
delete_item incorrectly states $line is an item_number/item_id but the
implementation unsets by cart index ($items[$line]) — either update the docblock
to state $line is the cart line key or change delete_item to locate and remove
the item by its item_number or item_id; to change behavior, iterate
$this->get_cart() to find an element where item['item_number'] == $line or
item['item_id'] == $line, unset that entry, and then call
$this->set_cart($items); ensure you update/remove references to $line typing if
switching semantics so callers and get_cart/set_cart remain consistent.
🧹 Nitpick comments (9)
app/Views/reports/graphs/line.php (1)

66-78: Remove duplicated currency prefix/suffix computation.

The same PHP block is repeated three times (lines 66-78, 109-121, 130-142). Since PHP variables remain in scope throughout the view file, compute the values once and reuse them.

♻️ Proposed refactor to remove duplication

Keep only the first block (lines 66-78) and remove the other two:

             }
         }),

-            <?php
-                $currency_symbol = esc($config['currency_symbol'], 'js');
-                $currency_prefix = '';
-                $currency_suffix = '';
-
-                if ($show_currency) {
-                    if (is_right_side_currency_symbol()) {
-                        $currency_suffix = $currency_symbol;
-                    } else {
-                        $currency_prefix = $currency_symbol;
-                    }
-                }
-            ?>
-
             Chartist.plugins.ctPointLabels({
             }),

-            <?php
-                $currency_symbol = esc($config['currency_symbol'], 'js');
-                $currency_prefix = '';
-                $currency_suffix = '';
-
-                if ($show_currency) {
-                    if (is_right_side_currency_symbol()) {
-                        $currency_suffix = $currency_symbol;
-                    } else {
-                        $currency_prefix = $currency_symbol;
-                    }
-                }
-            ?>
-
             Chartist.plugins.tooltip({

Also applies to: 109-121, 130-142

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Views/reports/graphs/line.php` around lines 66 - 78, Compute
$currency_symbol, $currency_prefix and $currency_suffix once at the top of the
view (using $show_currency and is_right_side_currency_symbol()) and remove the
duplicated PHP blocks later in the file; keep the first occurrence that sets
$currency_symbol, $currency_prefix, and $currency_suffix and delete the
subsequent duplicate blocks so the rest of the template reuses those variables.
app/Views/reports/graphs/pie.php (1)

34-54: Currency formatting logic looks good; minor formatting nit on line 54.

The precomputed prefix/suffix approach is consistent with other graph views. However, line 54 has extra whitespace: ] }; — consider removing the extra spaces for consistency.

🧹 Fix formatting
             })
-        ]    };
+        ]
+    };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Views/reports/graphs/pie.php` around lines 34 - 54, Remove the extra
spaces before the closing object/statement after the plugins array: in the block
that defines plugins: [ Chartist.plugins.tooltip({ transformTooltipTextFnc:
function(value) { return '<?= $currency_prefix ?>' + value + '<?=
$currency_suffix ?>'; } }) ]    }; — collapse the whitespace so the end reads ]
}; to match surrounding formatting and keep the Chartist/plugins tooltip block
(transformTooltipTextFnc, currency_prefix, currency_suffix) intact.
app/Views/configs/system_info.php (1)

28-30: Consider using semantic HTML instead of inline styles.

The change from <strong> tags to inline font-weight: bold; reduces semantic meaning. Semantic HTML improves accessibility and maintainability.

♻️ Suggested refactor to restore semantic HTML
-                <p style="min-height: 14.7em; font-weight: bold;">General Info</p>
-                <p style="min-height: 10.5em; font-weight: bold;">User Setup</p><br>
-                <p style="font-weight: bold;">Permissions</p>
+                <p style="min-height: 14.7em;"><strong>General Info</strong></p>
+                <p style="min-height: 10.5em;"><strong>User Setup</strong></p><br>
+                <p><strong>Permissions</strong></p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Views/configs/system_info.php` around lines 28 - 30, Replace the inline
font-weight styling on the three <p> elements ("General Info", "User Setup",
"Permissions") with semantic HTML (e.g., use <strong> for inline emphasis or
appropriate heading tags like <h2>/<h3> for section titles) and remove the
inline style attributes; instead, apply a CSS class (e.g., .section-title) for
layout and spacing (min-height) in your stylesheet so styling is separated from
markup and the elements regain semantic meaning.
app/Config/Services.php (1)

66-66: Strengthen htmlPurifier() signature typing.

Line 66 still uses an untyped parameter and overly broad return type. Tightening this improves API safety and consistency.

Proposed diff
-    public static function htmlPurifier($getShared = true): object
+    public static function htmlPurifier(bool $getShared = true): HTMLPurifier

As per coding guidelines, "Write PHP 8.1+ compatible code with proper type declarations."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Config/Services.php` at line 66, Update the htmlPurifier signature to use
a typed boolean parameter and a concrete return type: change public static
function htmlPurifier($getShared = true): object to public static function
htmlPurifier(bool $getShared = true): \HTMLPurifier (or the correct concrete
purifier class used in your project), and ensure you import or fully qualify
that class; update any docblocks and call sites that rely on the old untyped
signature to match the new type hints.
app/Config/Cache.php (1)

175-197: Consider tightening cacheStatusCodes in production config.

Non-blocking suggestion: set this to [200] in production environments to reduce risk of caching transient error responses.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Config/Cache.php` around lines 175 - 197, Tighten the web page cache
status codes by setting the Cache class property public array $cacheStatusCodes
to only successful responses in production (e.g., [200]); update the assignment
inside the Cache configuration so it uses an environment check (like ENVIRONMENT
=== 'production' or env('APP_ENV') === 'production') to set $cacheStatusCodes =
[200] for production and keep the looser default ([]) for non-production,
ensuring the PageCache filter only caches 200 responses in prod.
app/Models/Employee.php (1)

411-411: Tighten get_logged_in_employee_info() return type to object|false.

The method only returns object (from the get_info() call which has return type object) or false. The current declaration includes unused types (float|array|int|string|stdClass|null) that create confusion.

♻️ Proposed type tightening
-    public function get_logged_in_employee_info(): float|false|array|int|string|stdClass|null
+    public function get_logged_in_employee_info(): object|false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Models/Employee.php` at line 411, Tighten the return type of
get_logged_in_employee_info() to only object|false by replacing the current
union (float|false|array|int|string|stdClass|null) with object|false; update the
function signature for get_logged_in_employee_info() and ensure any internal
call to get_info() (which returns object) and all callers accept object|false
accordingly to avoid type mismatches.
app/Views/errors/html/error_400.php (1)

72-82: Minor inconsistency in HTML indentation.

The .wrap container is not indented inside <body> here, whereas error_404.php keeps the indentation. This is purely cosmetic but may be worth aligning for consistency across error templates.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Views/errors/html/error_400.php` around lines 72 - 82, In error_400.php
adjust the HTML indentation so the <div class="wrap"> block is indented inside
the <body> to match the style used in error_404.php; locate the <div
class="wrap"> in error_400.php and re-indent its opening tag, inner <h1> and <p>
contents to the same nesting level as in error_404.php for consistent template
formatting.
app/Config/Database.php (1)

77-79: SQLite-specific options in MySQLi configuration.

The foreignKeys, busyTimeout, and synchronous options are SQLite-specific settings but the DBDriver is set to MySQLi. These options will be ignored for MySQL connections. Consider removing them for clarity, or document that they're placeholders for future SQLite testing support.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Config/Database.php` around lines 77 - 79, The config currently sets
SQLite-specific keys ('foreignKeys', 'busyTimeout', 'synchronous') while
DBDriver is MySQLi; remove these keys from the default MySQLi configuration or
move them into a separate SQLite config branch and/or add a guard that only
applies them when DBDriver === 'SQLite3' (refer to the DBDriver setting and the
array entries 'foreignKeys', 'busyTimeout', 'synchronous' in Database.php);
update comments to state these options are only for SQLite if you keep a
separate SQLite config.
app/Views/errors/cli/error_exception.php (1)

60-60: LGTM – Comment capitalization fix is appropriate.

The lowercase comment start follows typical inline comment style. The comment clarifies that null values return 'null' (lowercase) rather than var_export(null, true) which would return 'NULL' (uppercase).

Optional: Consider making the comment more explicit

If you'd like to make the intent even clearer, you could expand the comment:

-    $value === null   => 'null', // return the lowercased version
+    $value === null   => 'null', // return lowercase 'null' instead of var_export's 'NULL'

This is purely optional and not necessary for the current review.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/Views/errors/cli/error_exception.php` at line 60, Update the inline
comment on the expression "$value === null   => 'null'" so it uses the lowercase
word "null" (i.e., comment should read that null values return 'null' in
lowercase rather than 'NULL'); locate the comment adjacent to the "$value ===
null" expression and either keep the concise lowercase comment or, if you
prefer, make it slightly more explicit by stating that this branch returns the
string 'null' (lowercase) rather than the uppercase output of var_export.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/Config/ContentSecurityPolicy.php`:
- Line 200: The CSP setting objectSrc in ContentSecurityPolicy.php was relaxed
to 'self' which re-enables <object>/<embed>/<applet> from same-origin; restore
it to the safer default by changing the public $objectSrc back to 'none' in the
ContentSecurityPolicy class (symbol: objectSrc) unless you have a documented,
necessary use-case—if you must allow same-origin objects, add an inline comment
above objectSrc explaining the specific feature that requires it and
create/update project documentation describing the justification and any
mitigations (e.g., strict MIME type checks, input validation).

In `@app/Config/Filters.php`:
- Around line 68-71: Update the PHPDoc for the Filters::$globals property to
reflect that the 'before' and 'after' arrays can contain both numeric-indexed
string entries and string-keyed arrays (e.g., 'csrf' => ['except' => ...]);
change the type from the current union to a keyed shape such as array{before:
array<int|string, string|array{except: list<string>|string}>, after:
array<int|string, string|array{except: list<string>|string}>} so tools and
static analyzers understand the mixed keys and heterogeneous values for the
before/after lists.

In `@app/Controllers/Receivings.php`:
- Around line 193-197: postEditItem currently accepts null/empty item_id without
validation; add an explicit guard at the start of postEditItem to reject null or
empty strings (e.g., if ($item_id === null || $item_id === '' ||
trim((string)$item_id) === '') ) and return an appropriate error response (HTTP
400 / BadRequest or a JSON error / redirect with flash) instead of proceeding;
ensure you reference the postEditItem method and sanitize/cast the incoming
$item_id before using it in any lookup or DB calls.

In `@app/Models/Customer.php`:
- Line 132: The get_stats method currently declares an overly broad return
union; narrow it to match what $builder->get()->getRow() actually returns by
changing the return type of Customer::get_stats to stdClass|null (or ?stdClass)
and update any docblock/type hints accordingly so callers know it returns either
an object or null coming from $builder->get()->getRow().

In `@app/Models/Item.php`:
- Line 355: The method get_info_by_id_or_number currently declares an overly
broad return type; tighten it to reflect the actual outcomes by changing the
signature to return stdClass|string and ensure the code path that calls
$query->getRow() returns an object (stdClass) rather than an array (or adjust
conversion) so the declared type matches the actual return values from
get_info_by_id_or_number.

In `@app/Views/barcodes/barcode_sheet.php`:
- Around line 16-26: Escape all dynamic outputs and fix the CSS property: wrap
URL outputs like base_url() in esc(..., 'url') for the <link href>, and escape
all attribute/inline-style values from $barcode_config and the class built with
$barcode_lib->get_font_name(...) using esc(..., 'attr'); replace the invalid CSS
property "borderspacing" with "border-spacing" in the <table> style and ensure
barcode height/width/font-size/page-width/page-cellspacing values are escaped
before interpolation.
- Line 26: Replace the invalid CSS property and add a unit: change the inline
style on the <table> element that uses
$barcode_config['barcode_page_cellspacing'] so it uses the correct CSS property
name "border-spacing" (with a hyphen) and append a valid unit (e.g. "px") to the
cellspacing value (e.g. use $barcode_config['barcode_page_cellspacing'] with
"px"), leaving the existing width usage of
$barcode_config['barcode_page_width']% intact so the style becomes
border-spacing:<value>px; width:<value>%.

In `@app/Views/configs/system_info.php`:
- Around line 39-46: The issue is inconsistent inline CSS in the echo statements
for BC Math and INTL: they use style="color: red" (missing the terminating
semicolon and closing >) while others use style="color: red;">; update the two
occurrences (the echo lines that output "BC Math" and "INTL" and contain
'style="color: red"') to match the correct pattern used elsewhere (use
'style="color: red;">') so all extension status spans are syntactically
consistent.

In `@app/Views/errors/html/error_exception.php`:
- Around line 384-386: The echoed header index uses concatenation without
parentheses, causing operator precedence to compute ($i + ' ) ') incorrectly;
update the foreach over $value (variables $i and $header in the loop that calls
$header->getValueLine() and esc()) to wrap the addition in parentheses so it
outputs ($i + 1) correctly — i.e., change the expression that builds the string
around $i + 1 to explicitly evaluate ($i + 1) before concatenation.
- Around line 337-339: The string concatenation in the foreach over $value uses
`' ('. $i+1 . ') '` which misapplies operator precedence and causes PHP to try
adding 1 to a string; update the concatenation around the index in the foreach
(variables $i and $header, method getValueLine()) to explicitly group the
arithmetic, e.g. concatenate ' ('. ($i + 1) .') ' before the
esc($header->getValueLine(), 'html') call so the index increments correctly.

In `@app/Views/sales/invoice_email.php`:
- Around line 174-175: The payment_message from $config is rendered without
escaping (nl2br($config['payment_message'])) which allows HTML injection; update
invoice_email.php to escape the payment_message before applying nl2br (use
esc($config['payment_message']) or esc(..., 'html') depending on project
conventions) so output is sanitized, keeping the existing nl2br usage and
consistency with the comments line that already uses esc() for $comments.
- Around line 104-106: The discount cell condition uses item-level
$item['discount'] but the table schema/header is built from order-level
$discount causing missing <td> and misalignment; update the per-row condition in
invoice_email.php to check the same $discount variable used when building the
table (i.e., use $discount > 0) so each row renders the discount column
consistently, keeping the existing cell content
(to_currency($item['discounted_total'] / $item['quantity'])) intact.

In `@composer.json`:
- Around line 35-39: The composer.json currently requires PHP "^8.1" which
conflicts with packages like codeigniter4/framework v4.7.2 and
laminas/laminas-escaper 2.18.0 that need PHP 8.2+, so update the "php" platform
requirement in composer.json from "^8.1" to "^8.2" and then regenerate
dependencies (run composer update / composer install to refresh composer.lock)
to resolve the dependency conflict and ensure packages (e.g.,
codeigniter4/framework, laminas/laminas-escaper) install correctly.

---

Outside diff comments:
In `@app/Config/Database.php`:
- Around line 130-132: In the switch block inside the Database configuration
(class Database / the switch that sets $this->defaultGroup), replace the
incorrect semicolon after the 'development' case with the standard colon so the
case reads case 'development': before executing $this->defaultGroup =
'development'; and break; — this fixes the unconventional/typo syntax and aligns
the switch-case with normal PHP style.

In `@app/Libraries/Receiving_lib.php`:
- Around line 395-401: The docblock for delete_item incorrectly states $line is
an item_number/item_id but the implementation unsets by cart index
($items[$line]) — either update the docblock to state $line is the cart line key
or change delete_item to locate and remove the item by its item_number or
item_id; to change behavior, iterate $this->get_cart() to find an element where
item['item_number'] == $line or item['item_id'] == $line, unset that entry, and
then call $this->set_cart($items); ensure you update/remove references to $line
typing if switching semantics so callers and get_cart/set_cart remain
consistent.

---

Nitpick comments:
In `@app/Config/Cache.php`:
- Around line 175-197: Tighten the web page cache status codes by setting the
Cache class property public array $cacheStatusCodes to only successful responses
in production (e.g., [200]); update the assignment inside the Cache
configuration so it uses an environment check (like ENVIRONMENT === 'production'
or env('APP_ENV') === 'production') to set $cacheStatusCodes = [200] for
production and keep the looser default ([]) for non-production, ensuring the
PageCache filter only caches 200 responses in prod.

In `@app/Config/Database.php`:
- Around line 77-79: The config currently sets SQLite-specific keys
('foreignKeys', 'busyTimeout', 'synchronous') while DBDriver is MySQLi; remove
these keys from the default MySQLi configuration or move them into a separate
SQLite config branch and/or add a guard that only applies them when DBDriver ===
'SQLite3' (refer to the DBDriver setting and the array entries 'foreignKeys',
'busyTimeout', 'synchronous' in Database.php); update comments to state these
options are only for SQLite if you keep a separate SQLite config.

In `@app/Config/Services.php`:
- Line 66: Update the htmlPurifier signature to use a typed boolean parameter
and a concrete return type: change public static function
htmlPurifier($getShared = true): object to public static function
htmlPurifier(bool $getShared = true): \HTMLPurifier (or the correct concrete
purifier class used in your project), and ensure you import or fully qualify
that class; update any docblocks and call sites that rely on the old untyped
signature to match the new type hints.

In `@app/Models/Employee.php`:
- Line 411: Tighten the return type of get_logged_in_employee_info() to only
object|false by replacing the current union
(float|false|array|int|string|stdClass|null) with object|false; update the
function signature for get_logged_in_employee_info() and ensure any internal
call to get_info() (which returns object) and all callers accept object|false
accordingly to avoid type mismatches.

In `@app/Views/configs/system_info.php`:
- Around line 28-30: Replace the inline font-weight styling on the three <p>
elements ("General Info", "User Setup", "Permissions") with semantic HTML (e.g.,
use <strong> for inline emphasis or appropriate heading tags like <h2>/<h3> for
section titles) and remove the inline style attributes; instead, apply a CSS
class (e.g., .section-title) for layout and spacing (min-height) in your
stylesheet so styling is separated from markup and the elements regain semantic
meaning.

In `@app/Views/errors/cli/error_exception.php`:
- Line 60: Update the inline comment on the expression "$value === null   =>
'null'" so it uses the lowercase word "null" (i.e., comment should read that
null values return 'null' in lowercase rather than 'NULL'); locate the comment
adjacent to the "$value === null" expression and either keep the concise
lowercase comment or, if you prefer, make it slightly more explicit by stating
that this branch returns the string 'null' (lowercase) rather than the uppercase
output of var_export.

In `@app/Views/errors/html/error_400.php`:
- Around line 72-82: In error_400.php adjust the HTML indentation so the <div
class="wrap"> block is indented inside the <body> to match the style used in
error_404.php; locate the <div class="wrap"> in error_400.php and re-indent its
opening tag, inner <h1> and <p> contents to the same nesting level as in
error_404.php for consistent template formatting.

In `@app/Views/reports/graphs/line.php`:
- Around line 66-78: Compute $currency_symbol, $currency_prefix and
$currency_suffix once at the top of the view (using $show_currency and
is_right_side_currency_symbol()) and remove the duplicated PHP blocks later in
the file; keep the first occurrence that sets $currency_symbol,
$currency_prefix, and $currency_suffix and delete the subsequent duplicate
blocks so the rest of the template reuses those variables.

In `@app/Views/reports/graphs/pie.php`:
- Around line 34-54: Remove the extra spaces before the closing object/statement
after the plugins array: in the block that defines plugins: [
Chartist.plugins.tooltip({ transformTooltipTextFnc: function(value) { return
'<?= $currency_prefix ?>' + value + '<?= $currency_suffix ?>'; } }) ]    }; —
collapse the whitespace so the end reads ] }; to match surrounding formatting
and keep the Chartist/plugins tooltip block (transformTooltipTextFnc,
currency_prefix, currency_suffix) intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 076f11cc-8b20-4b63-b684-d82ef810cdaf

📥 Commits

Reviewing files that changed from the base of the PR and between 577cf55 and cb7d878.

⛔ Files ignored due to path filters (1)
  • composer.lock is excluded by !**/*.lock
📒 Files selected for processing (66)
  • app/Config/App.php
  • app/Config/Autoload.php
  • app/Config/Boot/testing.php
  • app/Config/CURLRequest.php
  • app/Config/Cache.php
  • app/Config/ContentSecurityPolicy.php
  • app/Config/Cookie.php
  • app/Config/Database.php
  • app/Config/DocTypes.php
  • app/Config/Email.php
  • app/Config/Encryption.php
  • app/Config/Filters.php
  • app/Config/Format.php
  • app/Config/Hostnames.php
  • app/Config/Images.php
  • app/Config/Logger.php
  • app/Config/Migrations.php
  • app/Config/Mimes.php
  • app/Config/Modules.php
  • app/Config/Optimize.php
  • app/Config/Paths.php
  • app/Config/Routing.php
  • app/Config/Security.php
  • app/Config/Services.php
  • app/Config/Session.php
  • app/Config/Toolbar.php
  • app/Config/UserAgents.php
  • app/Config/View.php
  • app/Config/WorkerMode.php
  • app/Controllers/BaseController.php
  • app/Controllers/Home.php
  • app/Controllers/Receivings.php
  • app/Helpers/tabular_helper.php
  • app/Helpers/url_helper.php
  • app/Libraries/MY_Language.php
  • app/Libraries/Receiving_lib.php
  • app/Models/Attribute.php
  • app/Models/Customer.php
  • app/Models/Employee.php
  • app/Models/Item.php
  • app/Views/barcodes/barcode_sheet.php
  • app/Views/cashups/manage.php
  • app/Views/configs/system_info.php
  • app/Views/errors/cli/error_exception.php
  • app/Views/errors/html/debug.css
  • app/Views/errors/html/error_400.php
  • app/Views/errors/html/error_404.php
  • app/Views/errors/html/error_exception.php
  • app/Views/expenses/manage.php
  • app/Views/partial/footer.php
  • app/Views/reports/graphs/bar.php
  • app/Views/reports/graphs/hbar.php
  • app/Views/reports/graphs/line.php
  • app/Views/reports/graphs/pie.php
  • app/Views/sales/invoice.php
  • app/Views/sales/invoice_email.php
  • app/Views/sales/manage.php
  • app/Views/sales/quote_email.php
  • app/Views/sales/register.php
  • app/Views/sales/work_order_email.php
  • app/Views/taxes/tax_categories.php
  • app/Views/taxes/tax_codes.php
  • app/Views/taxes/tax_jurisdictions.php
  • composer.json
  • preload.php
  • public/resources/.gitkeep
💤 Files with no reviewable changes (3)
  • app/Config/Modules.php
  • app/Config/Autoload.php
  • app/Config/DocTypes.php

Comment thread app/Config/ContentSecurityPolicy.php Outdated
Comment thread app/Config/Filters.php
Comment thread app/Controllers/Receivings.php
Comment thread app/Models/Customer.php Outdated
Comment thread app/Models/Item.php Outdated
Comment thread app/Views/errors/html/error_exception.php
Comment thread app/Views/errors/html/error_exception.php
Comment thread app/Views/sales/invoice_email.php Outdated
Comment thread app/Views/sales/invoice_email.php Outdated
Comment thread composer.json Outdated
@objecttothis
Copy link
Copy Markdown
Member Author

@objecttothis do squash the commits before merge. Btw if you like I can share an api key so you can use my ollama subscription. I was considering to swtich to github copilot next month as it offers more .models. The integration with github is better and you can then run agents fully in cloud wdyt

Yes I always squash commits when merging. Regarding the ollama subscription that would be great. Can you send it to me in an DM on gitter?

- Revert $objectSrc value in ContentSecurityPolicy.php
- Correct return type in Customer->get_stats()
- Correct return type in Item->get_info_by_id_or_number()
- Correct misspelling in border-spacing
- Added missing css style semicolons

Signed-off-by: objec <objecttothis@gmail.com>
- Resolve operator precedence ambiguity.
- Resolve column mismatch.
- Added missing escaping in view.
- Updated requirement for PHP 8.2

Signed-off-by: objec <objecttothis@gmail.com>
@objecttothis
Copy link
Copy Markdown
Member Author

@jekkos starting with CodeIgniter 4.7.0 PHP 8.2 is required. Can you remove
PHPUnit Tests / PHP 8.1 Tests (pull_request)
PHPUnit Tests / PHP 8.1 Tests (push)
and update PHP Linting / phplint (push) to no longer include PHP 8.0 or 8.1?

- Added PHP 8.2 requirement to the README.md

Signed-off-by: objec <objecttothis@gmail.com>
@objecttothis
Copy link
Copy Markdown
Member Author

@coderabbitai please create github issues for the unchecked tasklist items in this PR that call for a GitHub issue to be created.

@coderabbitai

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as low quality.

- Fixed duplicated `>` in app\Views\Expenses\manage.php
- Removed excess whitespace at the end of some lines in table_filter_persistence.php

Signed-off-by: objec <objecttothis@gmail.com>
- Added missing `>` in app\Views\Expenses\manage.php
- Corrected grammar in PHPdoc in table_filter_persistence.php

Signed-off-by: objec <objecttothis@gmail.com>
Signed-off-by: objec <objecttothis@gmail.com>
@jekkos
Copy link
Copy Markdown
Member

jekkos commented Apr 10, 2026

@jekkos starting with CodeIgniter 4.7.0 PHP 8.2 is required. Can you remove PHPUnit Tests / PHP 8.1 Tests (pull_request) PHPUnit Tests / PHP 8.1 Tests (push) and update PHP Linting / phplint (push) to no longer include PHP 8.0 or 8.1?

should we do it in this PR then? It also requires updating install / wiki instructions. Maybe you can release an agents to tackle that.

Would it make sense to try and release what we have currently in the master? There are already plenty of security fixes that we can release.

@objecttothis
Copy link
Copy Markdown
Member Author

@jekkos starting with CodeIgniter 4.7.0 PHP 8.2 is required. Can you remove PHPUnit Tests / PHP 8.1 Tests (pull_request) PHPUnit Tests / PHP 8.1 Tests (push) and update PHP Linting / phplint (push) to no longer include PHP 8.0 or 8.1?

should we do it in this PR then? It also requires updating install / wiki instructions. Maybe you can release an agents to tackle that.

I setup Ollama from the API key but I'm off for the weekend, so I can either release the agent on it on Monday or you can do it in a separate branch before if you would rather do it before Monday.

Would it make sense to try and release what we have currently in the master? There are already plenty of security fixes that we can release.

I found a regression in my testing of this code that I've narrowed down to likely saveAttributeLink() or saveAttributeValue() that is causing DROPDOWN attributes to not save correctly. When the form is submitted it results in the last added DROPDOWN value to save but all others get lost. This PR can get merged since the issue is in the master and a new PR needs to be created to fix the regression. After if we do other regression testing and don't find major regressions, I think we should publish a release.

Signed-off-by: objec <objecttothis@gmail.com>
@objecttothis
Copy link
Copy Markdown
Member Author

@jekkos starting with CodeIgniter 4.7.0 PHP 8.2 is required. Can you remove PHPUnit Tests / PHP 8.1 Tests (pull_request) PHPUnit Tests / PHP 8.1 Tests (push) and update PHP Linting / phplint (push) to no longer include PHP 8.0 or 8.1?

should we do it in this PR then? It also requires updating install / wiki instructions. Maybe you can release an agents to tackle that.

I setup Ollama from the API key but I'm off for the weekend, so I can either release the agent on it on Monday or you can do it in a separate branch before if you would rather do it before Monday.

Would it make sense to try and release what we have currently in the master? There are already plenty of security fixes that we can release.

I found a regression in my testing of this code that I've narrowed down to likely saveAttributeLink() or saveAttributeValue() that is causing DROPDOWN attributes to not save correctly. When the form is submitted it results in the last added DROPDOWN value to save but all others get lost. This PR can get merged since the issue is in the master and a new PR needs to be created to fix the regression. After if we do other regression testing and don't find major regressions, I think we should publish a release.

@jekkos, I found and fixed the bug causing DROPDOWN attribute values to not be saved when changing the definition. I just pushed it as part of this PR. Can you do a code review so that we can merge? I think after that we should be good to publish a release with the security patches in it.

- Update Linter to not include PHP 8.2 and 8.1
- Remove PHP 8.1 unit test cycle.
- Update Bug Report Template

Signed-off-by: objec <objecttothis@gmail.com>
coderabbitai[bot]

This comment was marked as resolved.

jekkos
jekkos previously approved these changes Apr 13, 2026
@jekkos
Copy link
Copy Markdown
Member

jekkos commented Apr 13, 2026

We might also want to update install.md and remove the old php version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade codeigniter4/framework from pinned 4.6.3 to ^4.7.2

2 participants