Skip to content

Latest commit

 

History

History
357 lines (304 loc) · 29.3 KB

File metadata and controls

357 lines (304 loc) · 29.3 KB

Version 4.8.0

Release Date: Unreleased

4.8.0 release of CodeIgniter4

  • TBD
  • The static Boot::initializeConsole() method no longer handles the display of the console header. This is now handled within Console::run(). If you have overridden Boot::initializeConsole(), you should remove any code related to displaying the console header, as this is now the responsibility of the Console class.
  • Commands: The -h option to routes command which was mapped previously to the --sort-by-handler option is now removed. Use --sort-by-handler instead to sort the routes by handler when running the routes command.
  • Commands: The filter:check command now requires the HTTP method argument to be uppercase (e.g., spark filter:check GET / instead of spark filter:check get /).
  • Commands: Several built-in commands have been migrated from BaseCommand to the modern AbstractCommand style. Applications that extend a built-in command to override behaviour may need to re-implement against the modern API (configure() + execute() and the #[Command] attribute) once the class it extends is migrated, or, preferably, compose instead of extending. Invocations on the command line are unaffected.
  • Commands: The success and error messages from debugbar:clear, cache:clear, and cache:info now include the affected path or cache driver/handler so the user can see which resource was acted on (or rejected). Scripts asserting on the prior literal text will need to be updated.
  • Commands: Declining the key:generate overwrite prompt interactively now returns EXIT_SUCCESS instead of EXIT_ERROR. Output messages were also reworded; CI/automation that branches on the exit code or greps the previous wording will need updating.
  • Commands: The migrate:rollback command no longer accepts the undocumented -g (database group) option. It never had any effect, since MigrationRunner::regress() ignores the group, and the modern command pipeline now rejects unknown options. Remove -g from any migrate:rollback invocation.
  • Commands: The logs:clear command now returns EXIT_SUCCESS (previously EXIT_ERROR) when the user declines the interactive confirmation prompt, since user-initiated cancellation is not a failure. Output messages have also been reworded to distinguish cancellation (interactive n) from abort (non-interactive without --force), and the resolved log directory path is now included in the prompt, success, and failure messages.
  • Database: The Postgre driver's $db->error()['code'] previously always returned ''. It now returns the 5-character SQLSTATE string for query and transaction failures (e.g., '42P01'), or '08006' for connection-level failures. Code that relied on $db->error()['code'] === '' will need updating.
  • Filters: HTTP method matching for method-based filters is now case-sensitive. The keys in Config\Filters::$methods must exactly match the request method (e.g., GET, POST). Lowercase method names (e.g., post) will no longer match.
  • Testing: Tests using the FeatureTestTrait must now use uppercase HTTP method names when performing a request when using the call() method directly (e.g., $this->call('GET', '/path') instead of $this->call('get', '/path')). Additionally, setting method-based routes using withRoutes() must also use uppercase method names (e.g., $this->withRoutes([['GET', 'home', 'Home::index']])).

NOTE: If you've implemented your own classes that implement these interfaces from scratch, you will need to update your implementations to include the new methods or method changes to ensure compatibility.

  • Cache: CodeIgniter\Cache\CacheInterface::remember() now accepts a TTL callable. Custom implementations of CacheInterface must update the $ttl parameter type from int to callable|int.
  • Database: CodeIgniter\Database\ConnectionInterface now requires the afterCommit(), afterRollback(), inTransaction(), and transaction() methods.
  • Logging: CodeIgniter\Log\Handlers\HandlerInterface::handle() now requires a third parameter array $context = []. Any custom log handler that overrides handle() - whether implementing HandlerInterface directly or extending a built-in handler class - must add the parameter to its handle() method signature.
  • Security: The SecurityInterface's verify() method now has a native return type of static.
  • Validation: CodeIgniter\Validation\ValidationInterface now requires the getValidatedInput() method, which returns a CodeIgniter\Validation\ValidatedInput instance.
  • CLI: The Console::run() method now accepts an optional array $tokens parameter. This allows you to pass an array of command tokens directly to the console runner, which is useful for testing or programmatically running commands. If not provided, it will default to using the global $argv.
  • CodeIgniter: The deprecated parameters in methods have been removed:
    • CodeIgniter\CodeIgniter::handleRequest() no longer accepts the deprecated $cacheConfig and $returnResponse parameters.
      • $cacheConfig is no longer used and is now hard deprecated. A deprecation notice will be triggered if this is passed to the method.
      • $returnResponse is now removed since already deprecated and unused.
      • The updated method signature is now handleRequest(?RouteCollectionInterface $routes, ?Cache $cacheConfig = null).
    • CodeIgniter\CodeIgniter::gatherOutput() no longer accepts the deprecated $cacheConfig parameter. As this is the first parameter, custom uses of this method will need to be updated to remove the parameter.
  • Config: CodeIgniter\Config\Services::request() no longer accepts any parameter.
  • Database: The following methods have had their signatures updated to remove deprecated parameters:
    • CodeIgniter\Database\Forge::_createTable() no longer accepts the deprecated $ifNotExists parameter. The method signature is now _createTable(string $table, array $attributes).
  • HTTP: The following properties have changed their scope (visibility):
    • CodeIgniter\HTTP\RequestTrait::$ipAddress is now private (previously protected).
  • HTTP: The following methods have changed their scope (visibility):
    • CodeIgniter\HTTP\URI::setUri() is now private (previously public).
    • CodeIgniter\HTTP\URI::refreshPath() is now protected (previously public).
    • CodeIgniter\HTTP\SiteURI::refreshPath() is now protected (previously public).
  • Autoloader: Removed the following deprecated methods:
    • CodeIgniter\Autoloader\Autoloader::sanitizeFileName()
    • CodeIgniter\Autoloader\Autoloader::discoverComposerNamespaces()
  • Bootstrap: The deprecated system/bootstrap.php file has been removed.
  • Cache: Removed the following deprecated methods and constant:
    • CodeIgniter\Cache\Handlers\BaseHandler::RESERVED_CHARACTERS (deprecated since v4.1.5)
    • CodeIgniter\Cache\Handlers\FileHandler::writeFile() (deprecated since v4.6.0)
    • CodeIgniter\Cache\Handlers\FileHandler::deleteFile() (deprecated since v4.6.0)
    • CodeIgniter\Cache\Handlers\FileHandler::getDirFileInfo() (deprecated since v4.6.0)
    • CodeIgniter\Cache\Handlers\FileHandler::getFileInfo() (deprecated since v4.6.0)
  • CLI: Removed the following properties and methods deprecated:
    • CodeIgniter\CLI\BaseCommand::getPad()
    • CodeIgniter\CLI\CLI::$readline_support
    • CodeIgniter\CLI\CLI::$wait_msg
    • CodeIgniter\CLI\CLI::isWindows()
    • CodeIgniter\CLI\GeneratorTrait::execute()
  • CodeIgniter: Removed the following properties and methods deprecated:
    • CodeIgniter\CodeIgniter::$cacheTTL
    • CodeIgniter\CodeIgniter::$returnResponse
    • CodeIgniter\CodeIgniter::initializeKint()
    • CodeIgniter\CodeIgniter::detectEnvironment()
    • CodeIgniter\CodeIgniter::bootstrapEnvironment()
    • CodeIgniter\CodeIgniter::forceSecureAccess()
    • CodeIgniter\CodeIgniter::displayCache()
    • CodeIgniter\CodeIgniter::cache()
    • CodeIgniter\CodeIgniter::cachePage()
    • CodeIgniter\CodeIgniter::generateCacheName()
    • CodeIgniter\CodeIgniter::displayPerformanceMetrics()
    • CodeIgniter\CodeIgniter::determinePath()
    • CodeIgniter\CodeIgniter::callExit()
    • CodeIgniter\Test\MockCodeIgniter::callExit()
  • Config: Removed the following property deprecated:
    • CodeIgniter\Config\BaseService::$services (deprecated since v4.5.0)
  • Database: Removed the following properties and methods deprecated:
    • CodeIgniter\Database\BaseBuilder::setInsertBatch()
    • CodeIgniter\Database\BaseBuilder::setUpdateBatch()
    • CodeIgniter\Database\BaseBuilder::cleanClone()
    • CodeIgniter\Database\BaseConnection::$strictOn
    • CodeIgniter\Database\Forge::$createTableIfStr
    • CodeIgniter\Database\Seeder::$faker
    • CodeIgniter\Database\Seeder::faker()
    • CodeIgniter\Database\OCI8\Forge::$createTableIfStr
    • CodeIgniter\Database\OCI8\Forge::getError()
    • CodeIgniter\Database\SQLSRV\Forge::$createTableIfStr
  • Debug: Removed the following deprecated properties and methods:
    • CodeIgniter\Debug\Toolbar\Collectors\BaseCollector::cleanPath() (deprecated since v4.2.0)
    • CodeIgniter\Debug\Exceptions::$ob_level (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::$viewPath (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::determineView() (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::render() (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::collectVars() (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::maskSensitiveData() (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::maskData() (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::cleanPath() (deprecated since v4.2.0)
    • CodeIgniter\Debug\Exceptions::describeMemory() (deprecated since v4.4.0)
    • CodeIgniter\Debug\Exceptions::highlightFile() (deprecated since v4.4.0)
  • Exceptions: Removed the following static constructors of FrameworkException and its child classes:
    • CodeIgniter\Exceptions\DownloadException::forCannotSetCache()
    • CodeIgniter\Exceptions\FrameworkException::forMissingExtension()
    • CodeIgniter\Honeypot\Exceptions\HoneypotException::forNoHiddenValue()
    • CodeIgniter\HTTP\Exceptions\HTTPException::forInvalidSameSiteSetting()
    • CodeIgniter\Security\Exceptions\SecurityException::forInvalidSameSite()
    • CodeIgniter\Session\Exceptions\SessionException::forInvalidSameSiteSetting()
  • Filters: Removed the following properties and methods deprecated:
    • CodeIgniter\Filters\Filters::$arguments (deprecated since v4.6.0)
    • CodeIgniter\Filters\Filters::$argumentsClass (deprecated since v4.6.0)
    • CodeIgniter\Filters\Filters::getArguments() (deprecated since v4.6.0)
  • HTTP: Removed the following properties and methods deprecated:
    • CodeIgniter\HTTP\Message::getHeaders() (deprecated since v4.0.5)
    • CodeIgniter\HTTP\Message::getHeader() (deprecated since v4.0.5)
    • CodeIgniter\HTTP\RequestTrait::getEnv() (deprecated since v4.4.4)
    • CodeIgniter\HTTP\URI::$uriString (deprecated since v4.4.0)
    • CodeIgniter\HTTP\URI::$baseURL (deprecated since v4.4.0)
    • CodeIgniter\HTTP\URI::setBaseURL() (deprecated since v4.4.0)
    • CodeIgniter\HTTP\URI::getBaseURL() (deprecated since v4.4.0)
    • CodeIgniter\HTTP\URI::setScheme() (deprecated since v4.4.0)
    • CodeIgniter\HTTP\SiteURI::$segments (deprecated since v4.4.0)
    • CodeIgniter\HTTP\SiteURI::setBaseURL() (deprecated since v4.4.0)
    • CodeIgniter\HTTP\SiteURI::setURI() (deprecated since v4.4.0)
  • Security: Removed the following properties and methods deprecated:
    • CodeIgniter\Security\SecurityInterface::sanitizeFilename() (deprecated since v4.6.2)
    • CodeIgniter\Security\Security::sanitizeFilename() (deprecated since v4.6.2)
    • CodeIgniter\Security\Security::$csrfProtection (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$tokenRandomize (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$tokenName (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$headerName (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$expires (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$regenerate (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$redirect (deprecated since v4.4.0)
    • CodeIgniter\Security\Security::$sameSite (deprecated since v4.4.0)
  • Added a new attribute-based command style built on :php:class:`AbstractCommand <CodeIgniter\\CLI\\AbstractCommand>` and the #[Command] attribute, with configure() / isAvailable() / initialize() / interact() / execute() hooks and typed Argument / Option definitions. The legacy BaseCommand style continues to work. See :doc:`../cli/cli_modern_commands`.
  • Every modern command now ships with a --no-interaction / -N flag that skips the interact() hook, plus public isInteractive() / setInteractive() methods on AbstractCommand. isInteractive() also auto-detects piped or CI environments by probing STDIN for a TTY, and the state cascades to sub-commands invoked via $this->call(...). See :ref:`non-interactive-mode`.
  • spark help <command> now shows the default value of each option that accepts a value (e.g., [default: "file"]), the same way argument defaults are already displayed. Boolean flags and negatable toggles, which have no meaningful default to show, are unaffected.
  • You can now retrieve the last executed command in the console using the new Console::getCommand() method. This is useful for logging, debugging, or any situation where you need to know which command was run.
  • CLI now supports the -- separator to mean that what follows are arguments, not options. This allows you to have arguments that start with - without them being treated as options. For example: spark my:command -- --myarg will pass --myarg as an argument instead of an option.
  • CLI now supports options with values specified using an equals sign (e.g., --option=value) in addition to the existing space-separated syntax (e.g., --option value). This provides more flexibility in how you can pass options to commands.
  • CLI now supports parsing array options written multiple times (e.g., --option=value1 --option=value2) into an array of values. This allows you to easily pass multiple values for the same option without needing to use a comma-separated string. When used with CLI::getOption(), an array option will return its last value (for example, in this case, value2). To retrieve all values for an array option, use CLI::getRawOption().
  • Likewise, the command() function now also supports the above enhancements for command-line option parsing when using the function to run commands from code.
  • Added make:request generator command to scaffold :ref:`Form Request <form-requests>` classes.
  • Added key:rotate command to demote the current encryption.key to encryption.previousKeys in .env and generate a new key. See :ref:`spark-key-rotate`.
  • Added AbstractCommand::callSilently() to invoke another command with its output discarded, restoring the prior IO afterwards. See :ref:`modern-commands-call-silently`.
  • The migrate, migrate:rollback, migrate:refresh, and migrate:status commands now accept long option names (--namespace, --group, --batch, --force) alongside their existing short forms (-n, -g, -b, -f).
  • Added :php:class:`NullInputOutput <CodeIgniter\\CLI\\NullInputOutput>`, an :php:class:`InputOutput <CodeIgniter\\CLI\\InputOutput>` sink that discards all writes and returns an empty string from input().
  • The spark routes command now resolves the Before/After Filters columns for routes that use custom placeholders registered via $routes->addPlaceholder(). Sample URIs for custom placeholders are derived from the placeholder regex when possible, and can be overridden through the new $placeholderSamples property in Config\Routing. See :ref:`placeholder-samples-for-spark-routes`.
  • Added afterCommit() and afterRollback() transaction callbacks to database connections. These callbacks run after the outermost transaction commits or rolls back. See :ref:`transactions-transaction-callbacks`.
  • Added inTransaction() to database connections to check whether the connection is inside an active CodeIgniter-managed transaction. See :ref:`transactions-checking-transaction-state`.
  • Prepared query execution failures now throw or store typed database exceptions such as UniqueConstraintViolationException and RetryableTransactionException when applicable, matching normal query failures.
  • Added RetryableTransactionException for driver-specific retryable transaction failures such as deadlocks and serialization failures. See :ref:`transactions-retryable-exceptions`.
  • Added the transaction() method to database connections to run a callback inside a transaction, with optional retry attempts for retryable transaction failures and scoped transException and resetTransStatus options. See :ref:`transactions-closure`.
  • Added trustServerCertificate option to SQLSRV database connections in Config\Database. Set it to true to trust the server certificate without CA validation when using encrypted connections.
  • Added exists() and doesntExist() to Query Builder to check whether the current Query Builder query would return at least one row. See :ref:`query-builder-exists`.
  • Added explain() to Query Builder to run execution-plan queries for the current SELECT query. See :ref:`query-builder-explain`.
  • Added havingBetween(), orHavingBetween(), havingNotBetween(), and orHavingNotBetween() to Query Builder. See :ref:`query-builder-having-between`.
  • Added whereBetween(), orWhereBetween(), whereNotBetween(), and orWhereNotBetween() to Query Builder. See :ref:`query-builder-where-between`.
  • Added whereColumn() and orWhereColumn() to compare one column to another column while protecting identifiers by default. See :ref:`query-builder-where-column`.
  • Added whereExists(), orWhereExists(), whereNotExists(), and orWhereNotExists() to add EXISTS and NOT EXISTS subquery conditions. See :ref:`query-builder-where-exists`.
  • Added new incrementMany() and decrementMany() methods to CodeIgniter\Database\BaseBuilder for performing bulk increment/decrement operations.
  • Added lockForUpdate() to add pessimistic write locks to SELECT queries on supported drivers. See :ref:`query-builder-lock-for-update`.
  • Added a Copy Details button to detailed HTML exception pages.
  • Added new chunkRows() method to CodeIgniter\Model for processing large datasets in smaller chunks.
  • Added new firstOrInsert() method to CodeIgniter\Model that finds the first row matching the given attributes or inserts a new one. See :ref:`model-first-or-insert`.
  • Cache: Added support for TTL callables in the remember() method of cache handlers. This allows you to specify a callable that returns a TTL value, which can be useful for dynamic TTL.
  • Context: This new feature allows you to easily set and retrieve normal or hidden contextual data for the current request. See :ref:`Context <context>` for details.
  • Images:: Added support for the AVIF file format.
  • Locks: Added :doc:`Atomic Locks </libraries/locks>` for owner-aware, cross-process mutual exclusion backed by supported cache handlers: File, Redis, Predis, and Memcached. Memcached support has driver-specific release limitations because Memcached has no atomic compare-and-delete command.
  • Logging: Log handlers now receive the full context array as a third argument to handle(). When $logGlobalContext is enabled, the CI global context is available under the HandlerInterface::GLOBAL_CONTEXT_KEY key. Built-in handlers append it to the log output; custom handlers can use it for structured logging.
  • Logging: Added :ref:`per-call context logging <logging-per-call-context>` with three new Config\Logger options ($logContext, $logContextTrace, $logContextUsedKeys). Per PSR-3, a Throwable in the exception context key is automatically normalized to a meaningful array. All options default to false.
  • Security: Added :ref:`Fetch Metadata based CSRF protection <csrf-fetch-metadata>` with token fallback.
  • Added the retry option to CURLRequest for retrying failed responses with configurable delays, retryable status codes, optional transient cURL error retries, and Retry-After support. See :ref:`curlrequest-request-options-retry`.
  • Added :ref:`Form Requests <form-requests>` - a new FormRequest base class that encapsulates validation rules, custom error messages, and authorization logic for a single HTTP request.
  • Added IncomingRequest::input() to read GET, POST, JSON, and raw request data through InputData.
  • Added SSEResponse class for streaming Server-Sent Events (SSE) over HTTP. See :ref:`server-sent-events`.
  • Response and its child classes no longer require Config\App passed to their constructors. Consequently, CURLRequest's $config parameter is unused and will be removed in a future release.
  • Response now lazily loads the ContentSecurityPolicy, Cookie, and CookieStore classes only when used, instead of instantiating them on every request in the constructor. Requests that do not touch CSP or cookies no longer incur the cost of loading these classes.
  • CLIRequest now supports the -- separator to mean that what follows are arguments, not options. This allows you to have arguments that start with - without them being treated as options. For example: php index.php command -- --myarg will pass --myarg as an argument instead of an option.
  • CLIRequest now supports options with values specified using an equals sign (e.g., --option=value) in addition to the existing space-separated syntax (e.g., --option value). This provides more flexibility in how you can pass options to CLI requests.
  • Added $enableStyleNonce and $enableScriptNonce options to Config\App to automatically add nonces to control whether to add nonces to style-* and script-* directives in the Content Security Policy (CSP) header when CSP is enabled. See :ref:`csp-control-nonce-generation` for details.
  • Added URI::withQueryVar() and URI::withQueryVars() to return a cloned URI with query variables added or replaced.
  • URI now accepts an optional boolean second parameter in the constructor, defaulting to false, to control how the query string is parsed in instantiation. This is the behavior of ->useRawQueryString() brought into the constructor for convenience. Previously, you need to call $uri->useRawQueryString(true)->setURI($uri) to get this behavior. Now you can simply do new URI($uri, true).
  • CLIRequest now supports parsing array options written multiple times (e.g., --option=value1 --option=value2) into an array of values. This allows you to easily pass multiple values for the same option without needing to use a comma-separated string. When used with CLIRequest::getOption(), an array option will return its last value (for example, in this case, value2). To retrieve all values for an array option, use CLIRequest::getRawOption().
  • Custom rule methods that set an error via the &$error reference parameter now support the {field}, {param}, and {value} placeholders, consistent with language-file and setRule()/setRules() error messages.
  • Added Validation::getValidatedInput() to access validated data through a ValidatedInput object.
  • Float and Double Casting: Added support for precision and rounding mode when casting to float or double in entities.
  • Added CodeIgniter\Input\InputData and InputDataFactory for reusable typed input data objects.
  • Float and Double casting now throws CastException::forInvalidFloatRoundingMode() if an rounding mode other than up, down, even or odd is provided.
  • Environment: Added CodeIgniter\EnvironmentDetector class and corresponding environment service as a mockable wrapper around the ENVIRONMENT constant. Framework internals that previously compared ENVIRONMENT directly now go through this service, making environment-specific branches reachable in tests via Services::injectMock(). See :ref:`environment-detector-service`.
  • Time: Added Time::between(), Time::min(), and Time::max() comparison helpers. See :ref:`between <time-comparing-two-times-between>`, :ref:`min <time-comparing-two-times-min>`, and :ref:`max <time-comparing-two-times-max>`.
  • Added new language key:
    • Cache.unsupportedLockStore (CacheException::forUnsupportedLockStore())
  • Removed deprecated language keys tied to removed exception constructors:
    • Core.missingExtension (FrameworkException::forMissingExtension())
    • HTTP.cannotSetCache (DownloadException::forCannotSetCache())
    • HTTP.disallowedAction
    • HTTP.invalidSameSiteSetting (HTTPException::forInvalidSameSiteSetting())
    • Security.invalidSameSite (SecurityException::forInvalidSameSite())
    • Session.invalidSameSiteSetting (SessionException::forInvalidSameSiteSetting())
  • Config: Added the md key for Config\Mimes::$mimes for Markdown files.
  • CLI: The CLI::parseCommandLine() method is now deprecated and will be removed in a future release. The CLI class now uses the new CommandLineParser class to handle command-line argument parsing.
  • CLI: Returning a non-integer exit code from a command is now deprecated and will trigger a deprecation notice. Command methods should return an integer exit code (e.g., 0 for success, non-zero for errors) to ensure proper behavior across all platforms.
  • CLI: Commands::run() is now deprecated in favor of Commands::runLegacy() for legacy BaseCommand commands, and Commands::runCommand() for modern AbstractCommand commands.
  • CLI: The $commands parameter of Commands::verifyCommand() and the $collection parameter of Commands::getCommandAlternatives() are no longer used. Passing a non-empty array for either will trigger a deprecation notice.
  • HTTP: The CLIRequest::parseCommand() method is now deprecated and will be removed in a future release. The CLIRequest class now uses the new CommandLineParser class to handle command-line argument parsing.
  • HTTP: URI::setSilent() is now hard deprecated. This method was only previously marked as deprecated. It will now trigger a deprecation notice when used.

See the repo's CHANGELOG.md for a complete list of bugs fixed.