Change Log 1.8

CF

  • Add support for PHP 8.4
  • Fix the missing cf marker file that phpcf needs to locate the framework root
  • Fix a shadowed loop variable in cstr::is() and cstr::isMatch()
  • Fix cstr::replaceLast() missing an empty-search guard
  • Fix c::get() eagerly computing array_key_first()/array_key_last() on every path segment

CRouting

  • Security: CController::callAction() only calls public methods; protected and private return 404
  • Security: block magic methods (__construct, __call, …) from being routed
  • Security: block internal controller methods via CController::getBlockedMethods()
  • Security: CRouting_RouteFinder rejects methods inherited from the CController base class
  • Auto-discovered routes support HTTP verb prefixes on method names (getDetail(), postStore(), putUpdate(), deleteRemove(), anyProcess()); an unprefixed name still answers every verb
  • The wrong HTTP verb returns 405 Method Not Allowed with an Allow header instead of 404
  • Controllers using __call as a catch-all keep working

CDatabase

  • Fix compileTableExists() signatures in the Sqlite, SqlServer, and Odbc grammars, and the PostgresBuilder caller
  • Fix CDatabase_Query_Grammar_SqlServerGrammar::wrapTable() having a signature incompatible with its parent — a fatal the instant the dialect was instantiated
  • Fix CDatabase_Schema_Grammar_{Postgres,SqlServer}Grammar being completely unloadable from LSP-violating signatures, and the same bug in MariaDbGrammar::compileRenameColumn()
  • Fix CDatabase_Schema_Grammar_SqlServerGrammar never overriding wrapValue(), so it quoted identifiers with double quotes instead of square brackets
  • Fix CDatabase_Query_Grammar::compileBasicHaving()/compileHavingBetween() duplicating the boolean prefix, producing having and and …
  • Fix CDatabase_Schema_Blueprint::removeColumn() reading $c['attributes']['name'] on a CBase_Fluent — every call threw
  • Fix CDatabase_Schema_Blueprint::dropTimestamps()/timestampsTz() using the common created_at/updated_at naming while timestamps() creates created/updated
  • Fix the transactionsManager property typo in handleRollBackException(), which skipped the rollback on lost-connection errors
  • Fix ModelDataProvider correlating belongsToMany sort subqueries ("Subquery returns more than 1 row")
  • Fix CDatabase_Query_Builder::addSelect() shadowing its own $column parameter, and a garbled paginate() docblock
  • Treat MySQL error 1020 as a retryable concurrency error alongside deadlocks and lock wait timeouts
  • PHP 7.4 compatibility in CDatabase_Grammar and the Schema Builder: replace str_contains(), ??=, match(), first-class callables, and deprecated interpolation
  • Add missing PHPDoc across the CDatabase_Connection compat methods and CDatabase_Schema_MongoDB_Blueprint

CModel

  • Fix CModel_Nested_NestedSet::isNode() checking CModel_Nested_Trait, an unused alias, so every nested-set relation threw Model must be node
  • Fix CModel_Trait_Attributes using a bare Attribute::class, which resolved to PHP's built-in \Attribute and silently disabled the whole CModel_Casts_Attribute accessor/mutator feature
  • Fix CModel_Casts_Attribute missing the $withCaching property that Attributes.php reads unconditionally
  • Security: fix bearer-token lookup hashing the incoming token with c::hash() (salted per call) instead of a deterministic hash('sha256', …), which broke bearer-token auth entirely
  • Fix CModel_Collection::contains() always forwarding three arguments to its parent, breaking operatorForWhere()'s func_num_args() dispatch
  • Fix MetableTrait::setManyMeta() calling a nonexistent unsetRelation('meta'), plus a deprecated ${var} interpolation in scopeOrderByMetaNumeric()
  • Scope CacheableTrait's cache-key flush file per app instead of one shared path
  • Add the TranslationHasBeenSet event and expand HasTranslationTrait
  • Nested set: fix bootNestedTrait() never registering the deleted/restored events, so deleting a node orphaned every descendant and silently corrupted the tree
  • Nested set: fix setDepthWithSubtree() never cascading a moved subtree's new depth, and actionBeforeOrAfter()/actionRoot() never calling it at all
  • Nested set: fix refreshNode() only re-fetching lft/rgt, leaving depth stale
  • Nested set: fix fixTree()/rebuildTree() deriving depth from an unsaved parent, compounding errors down the tree
  • Nested set: fix restoreDescendants() calling getDeletedAtColumn(), which does not exist on this framework's primary soft-delete trait
  • Nested set: fix rawNode()'s $depth == null check to === null
  • Nested set: add tests/Model/NestedSetTest.php (26 tests) against a real database; document CModel_Nested_Move and CModel_Nested_Builder as dead code
  • Fix PHPDoc parse errors in CModel/CModel_Query and a wrong @throws in CModel_Trait_Attributes

CCollection

  • whereInstanceOf() accepts class-string[] as well as a single class-string
  • Add the missing LazyCollection methods sliding, containsOneItem, hasAny, dot, firstOrFail, toBase, sole, and mapTransform

CPeriod

  • Fix start()/end() reading an undefined $this->start/$this->end — both always threw, and so did asString()
  • Fix overlap() passing a stray static::class argument, which also broke overlapAny()/diffSymmetric()
  • Fix gap()/subtract()/renew()/touchesWith()/getIterator() mutating the original period, since CCarbon mutates in place
  • Complete PHPDoc across CPeriod and its traits, correcting several wrong return types to CCarbon

CElement

  • Any CElement subclass may declare protected $themeType to pick up extra classes from c::theme('<key>.classes')
  • Add CElement_FormInput_Text::setIcon() and CElement_FormInput_Select::setIcon() — an input-group icon prepended to the field
  • CElement_FormInput_Text builds its <input> through the standard build() pipeline and registers as control:Text; fixes disabled and readonly being mutually exclusive; removes the dead $action/buttonPosition API
  • CElement_FormInput_FileAjax extends CElement_FormInput_File; acceptFile moves to the shared parent and both get control:File/control:FileAjax cres.js modules with client-side accept-file validation
  • Remove the dead $this->validation->validationClass() call from Text, File, Time, Checkbox, Checkbox_Switcher, Select, SelectTag, DateRange, Radio, and Date
  • Align CElement_FormInput::addValidation() with CElement_Component_Form's rule-based validation conventions
  • Rename CElement_FormInput_Text's $input_style/$button_position and CElement_FormInput_Select's $group_list/$dropdown_classes/$hide_search to camelCase, with compat accessors updated
  • Add CElement_FormInput_SelectTwo — Select2 with cres.js auto-init, AJAX search, format templates, dependsOn, and modal detection
  • Repeater: add setCanAdd, setCanDelete, setAddLabel, setDeleteLabel, setAddButtonClass, setDeleteButtonClass, setMaxItem; JS re-initializes controls in cloned rows
  • TreeView: consolidate the legacy CElement_Tree into CElement_Component_TreeView; setNodes() accepts a callable for per-node ajax lazy loading
  • Calendar: rework CElement_Component_Calendar around CalendarEvents/CalendarEvent; setEvents() accepts a callable; add fullCalendar i18n
  • File Manager: migrate the client side from the vendored fm.js into component:FileManager, fixing the move-to-folder picker, the download endpoint's Flysystem calls, mime icons, and the mobile tree toggle
  • File Manager: reject path traversal in item names and working dir, catch the Flysystem v3 delete exceptions, and fix the sort dropdown and a z-index conflict
  • Widget/TabList: rework into cres.js elements; Widget::setCollapse() now actually collapses, and nested ajax-loaded tab lists work
  • DataTable: non-ajax mode shows the configured empty-state label instead of a blank <tbody>
  • Chart component supports dataOptions; add setDataFromCollection to SelectSearch; support Bootstrap 5
  • Deprecated: addTemplate()/CElement_Template in favour of addView()
  • Complete PHPDoc across essentially the whole CElement_* namespace (several hundred files)
  • Fix setAjax(false), setActive(false), and setMultiple(false) being no-ops on ListGroup, Action, and File
  • Fix Textarea_Quill's constructor overwriting $toolbar with a void return, and Textarea_Summernote silently dropping its text-link-para preset
  • Fix FormInput_Time emitting a hardcoded template: 'dropdown', and FormInput_DateRange::setValueStart()/setValueEnd() never rendering
  • Fix DataTable::setDomain() never assigning its argument, and setDataFromQuery() discarding $dbConfig
  • Fix DataTable_Exporter::createEngine() building a wrong class name that fataled on every call
  • Fix DataTable_Cell doubling its own $js, DataTable_DataRow::exists() returning a truthy field name, and DataTable_Trait_CheckboxTrait::setCheckboxColumnWidth() not returning $this
  • Fix ProgressBar_ProgressHandler never populating $maxValue/$minValue, and PrismCode::build() registering prism.min.js twice
  • Fix Blockly_BlockHelper::renderMathRound() emitting the wrong block type, and Blockly_CategoryHelper::renderCategory()'s no-op str_replace('_', '_', …)
  • Fix QueryBuilder_Constant::FILTER_INPUT_CHECKBOX being 'number', and Metric_SimpleMetric declaring a duplicate ValueMetric class
  • Fix Chart_Morris concatenating a PHP array into JS instead of json_encode()-ing it
  • Fix CTrait_Compat_Element_FormInput_File's docblock, which wrongly claimed none of its properties are read

CNavigation

  • Fix the icon prefix logic in SidenavRenderer, MenuRenderer, and the navigation helper for Themify, Linearicons, and PE Icon 7
  • Fix the active sidenav link carrying an extra horizontal margin its siblings lacked
  • Remove the CApp::isAdministrator()-based nav-access bypass from every renderer and helper
  • Replace the deprecated ccfg::get('have_user_access') with CF::config('app.have_user_access')
  • Rename a foreach variable in CApp_Navigation_Helper::nav() that shadowed the $nav parameter
  • Add missing PHPDoc to CNavigation_Menu and ClosureRenderer; drop a redundant isAdministrator check in loadRoleNav()

CApp

  • Deprecated: capp.js — remove capp.js, cresenity.js, and cresenity/cresenity.bs4.js from the theme js array; its legacy Cresenity constructor stops cres.js from initialising
  • Deprecated: CApp_Cloud and the Cloud Server Info trait, flagged as a security risk
  • Deprecated: CApp::setTheme() in favour of c::manager()->theme()->setTheme()
  • Removed: CApp::isAdmin()/isAdministrator() and the /administrator/... URL-prefix nav-access bypass
  • Add Tabler Icons as a framework-wide icon module, and default CSS for Bootstrap 5
  • Complete PHPDoc across CApp, CApp_Message, and the rest of the CApp_* namespace (138 files) plus all of CNavigation
  • Fix CApp::$pwa's docblock and declare the undeclared $rendered property CApp_Concern_RendererTrait uses

CBase

  • Fix CBase_Vite resolving asset and manifest paths via CF::publicPath(), which is null for apps under the shared front controller; falls back to the app's default/media

CEnv

  • Fix CEnv::$adapter/$dotEnvAdapter docblocks typed @var bool

CServer

  • Add CServer_Server — SSH-capable server abstraction, so CServer_Memory, CServer_System, CServer_Storage, CServer_Php, and CServer_PhpInfo all work locally or remotely through one API
  • Add CRemote_SSH_Config — array or object config, key validation, public key derivation, and auth type constants
  • Add CServer_LetsEncrypt for local and remote SSL certificate management
  • Add CServer_Memory_OS_WINNT for Windows memory and swap info
  • Add CServer_Server support to CServer_Service_Beanstalkd
  • Fix SSH key loading to support Ed25519 and ECDSA (PublicKeyLoader::loadPrivateKey)
  • Improve SSH connection error messages
  • Cache SSH connections via SSHRepository, and subsystem instances per CServer_Server
  • Deprecated: CServer_Command — methods moved to CServer_Server

CTrait

  • Fix DependsOn::getDependsOnValueJavascript() missing a getQuerySelector() call
  • Complete PHPDoc across CTrait_Compat_Element, CRenderable, ActionList, and CDomain; fix CDomain::delete() deleting the wrong path and add CDomain::exists()

Cres JS

  • Add the SelectTwo control — reads cres-config, initialises Select2, handles dependsOn, and auto-detects modal z-index
  • Add the generic DependsOn runner in element/depends/
  • Add the TreeView, Calendar, and FileManager components under element/component/
  • Add ElementHistoryState — a namespaced per-element wrapper over the History.js port, so several elements can keep their own history entries
  • Repeater: add resetClonedControls() to clean up Select2 and cres-element state on cloned rows
  • Refactor DownloadProgress out of Cresenity.js into module/DownloadProgress.js
  • Fix History.onPopState() hijacking hash-based routing owned by unrelated code, which broke Swagger UI's deepLinking
  • Fix isUsingBootstrap() missing a return statement
  • Fix a handleJsonResponse typo in an error message
  • Fix the reload complete callback checking onBlock instead of onUnblock

CAjax

  • Ajax file upload returns errCode/errMessage, with the previous format wrapped in a data key
  • Translate the upload-failure messages via a new shared element/upload i18n group (en, en_US, id_ID)
  • Add the TYPE_TREE_VIEW and TYPE_CALENDAR engines

CApi

  • Fix CApi_HTTP_Request's request reconstruction dropping headers set directly via ->set()
  • Fix CApi_Docs_GeneratorFactory missing a dot in its config key (api.groups.{group}docs), so docs overrides were silently ignored
  • Fix select search on modal; support YouTube Shorts in the EditorJs component
  • Remove a duplicate formats key in config/api.php
  • Complete PHPDoc across the CApi_* namespace, CApp_Concern_ViewTrait, and CRouting_RouteData

CHTTP

  • Fix CHTTP_Sitemap::add() referencing a bare Sitemapable::class that resolves to nothing, so toSitemapTag() was never called
  • Fix CHTTP_Cookie::queued($key, $default) throwing a TypeError instead of returning a non-array $default
  • Complete PHPDoc across CHTTP_Request; add the missing @var on CHTTP_Middleware_HandleCors::$paths

CValidation

  • Fix CValidation::factory($data, $rules) using a loose != null check, so empty-array data returned the factory singleton instead of a validator

CNotification

  • Fix EmailChannel's undefined $sender when a mailer config is set
  • Fix the Nexmo channel missing a return statement
  • Fix the Watzap channel result being overwritten with a null response
  • Fix the Zenziva channel return statement left commented out
  • Fix MessageResult's constructor not storing the vendor response
  • Fix the MethodAbstract::onNotificatonSent typo
  • Remove the dead errCode/errMessage pattern in ChannelAbstract::handleResult()
  • Add complete PHPDoc across the notification system

CTranslation

  • Fix Translator::get() shadowing its own $locale parameter inside a loop
  • Remove system/i18n/en/ (31 files identical to en_US/) and the empty en_US/filemanager.php stub
  • Fix id_ID/core.php's driver_not_found using stale %s placeholders
  • Add Translation (i18n) documentation under The Basic

CTesting

  • Add a PHPUnit feature-test kernel (CTesting_TestCase) wired to the real container, with withoutMiddleware()/withMiddleware(), beforeApplicationDestroyed(), and a session reset in from()
  • Add assertDatabaseHas()/assertDatabaseMissing()/assertDatabaseCount()
  • Add Dusk-style browser testing (test:browser, make:browser-test, …), with ChromeDriver installed from the Chrome for Testing index
  • Fix RefreshDatabaseTrait disconnecting the shared global PDO connection after every rollback
  • Fix CApp_Auth::instance()'s per-guard cache outliving tearDown(), so actingAs() stopped working after the first test
  • Fix CObserver and CAuth_Manager singletons leaking state across tests
  • Fix TestResponse::assertSee() and a non-static self::$x bug in TestSuiteSorter
  • Fix CTesting_TestResponse's ArrayAccess methods not matching the PHP 8 signature
  • Fix phpcf test --testdox fataling on an LSP incompatibility in TestDoxPrinter
  • Rename the --browse env var to BROWSER_TEST_HEADLESS_DISABLED

CConsole

  • Add phpcf init — an interactive wizard replacing app:create, app:preset, and app:preset:admin; fixes --title never being written, a dead refresh() call, and bootstrap.php being overwritten on re-run
  • Port a popular interactive CLI prompts library to a PHP 7.4-compatible CConsole_Prompt_* library, reachable via c::prompt()
  • Fix phpcf test silently ignoring passthrough args, so --filter and file paths ran the entire suite anyway
  • system/stubs/config/app.stub reads environment and key from c::env(); add env.stub and env.example.stub
  • Fix nav.stub/bootstrap.stub using uppercase OR in defined('SYSPATH') or die(...)
  • bootstrap.stub calls c::manager()->theme()->setTheme() instead of the deprecated CApp::setTheme()
  • Fix an inaccurate @return on CConsole_Prompt::output() and a typo'd @param \CCCollection

CDaemon

  • Extract CDaemon_RunnerAbstract, removing duplication across CDaemon_Runner, Supervisor_Runner, and Supervisor_WorkerRunner
  • Move the network server classes from CDaemon/Worker/ to CDaemon/Server/, keeping the old names as wrappers
  • Add the CDaemon_Server facade, CDaemon_Server_EventLoop, and CDaemon_Server_Constant, replacing every Workerman reference
  • Move CDaemon_WorkerProcess to CDaemon_Supervisor_WorkerProcess (old name still works)
  • Add a configurable daemon.php_binary
  • Fix a parentPid assignment (== instead of =) in ServiceAbstract
  • PHP 8 compatibility: is_resource() checks for SysV handles, a shm_detach null guard, and a callCount type error
  • Add getCallCount()/setCallCount() to MediatorAbstract and checkEnvironment() to ViaInterface
  • Self-terminate a CDaemon_BackgroundProcess worker when its supervisor dies, instead of leaking orphans
  • Swallow console-output write failures instead of crashing the queue worker loop
  • Guard a vendored React\Promise method_exists() call against PHP 8.4's stricter TypeError
  • Fix Core_* PHPDoc references

CDevSuite

  • Fix devsuite:secure on Linux — the generated root CA was never trusted anywhere; add trustCa() auto-detecting update-ca-certificates, update-ca-trust, or trust
  • Fix Firefox NSS trust using a *.default glob that misses modern profile names; loop over every profile directory including the Snap path
  • Surface openssl/certutil failures instead of reporting success regardless, and check both during devsuite:install
  • Fix CDevSuite_Linux_Site::getCertificates() hardcoding a 4-character TLD assumption
  • Fix devsuite:tld calling the Windows-only Acrylic class on every platform, so dnsmasq never learnt the new TLD
  • Fix the standalone Linux devsuite bash CLI: a bash syntax error, a commented-out symlinkToUsersBin(), legacy ~/.devsuite/ paths, and dispatch to a nonexistent cli/devsuite.php
  • Fix CDevSuite_Linux_Db_MariaDB::uninstall() and CDevSuite_Mac_Db_MariaDB::install()/stop()/uninstall() being copy-pasted from Nginx, so MariaDB never stopped or uninstalled
  • Fix CDevSuite_Linux_PhpFpm::fpmServiceName() returning a DomainException instead of throwing it
  • Fix CDevSuite_Deploy::getOptions() referencing an undeclared $ignoreOptions, and implement the missing confirmTaskWithUser(); CDevSuite::confirm() now returns its answer
  • Fix CDevSuite_Deploy_RemoteProcessor::getProcess() having ~35 lines of unreachable code after a return
  • Fix CDevSuite_Filesystem::ensureDirExistsAsRoot() discarding $owner/$mode
  • Fix CDevSuite_Linux_Configuration::uninstall() passing an extra argument to isDir(), and an "Databaes" typo in CDevSuite_Ssh::existsOrExit()
  • Declare installDevSuiteDns(), nmRestart(), and getConfiguredServer() abstract on their base classes
  • Complete PHPDoc across the whole library and its devsuite:* command wrappers; remove the @author Hery tags

CReport

  • Add CReport_UIBuilder — an Alpine.js visual JasperReports-style designer reading and writing jrxml
  • Add CReport_DatasetRegistry — named datasets resolved to a data provider, with field descriptions for the builder and a preview-PDF flow
  • Add Excel export (CReport_Excel_*) mapping the cell-cuts algorithm onto a PhpSpreadsheet grid
  • Fix jrxml parsing: unparsed TextField pattern/textAdjust, rightMargin read from leftMargin, unparsed columnWidth, Rectangle::toJrXml() emitting <line>, and the numeric formatter crashing on PHP 8

Cresenity Demo App

  • Add Nestable, Nested Model, Summernote, Calendar, Tree View, and File Manager demos
  • Add a Report demo as its own top-level menu, plus a master-detail variant
  • Add a collapsible example to the Widget demo, and split the Validation demo into Form / Control-level / Database
  • Replace the defunct Google Image Charts API with QuickChart.io, and reskin the Query Builder demo

CBroadcast

  • Add an opt-in verify option to Pusher broadcast configs, for local WebSocket daemons over TLS with a hostname mismatch

CResource

  • Retry a resource download before throwing UnreachableUrl — DigitalOcean Spaces redirect URLs can be briefly unreachable after upload

CHouseKeeping

  • Fix a missing return statement in CHouseKeeping_Database_LogActivity

CPagination

  • Add #[\ReturnTypeWillChange] to the ArrayAccess, Countable, IteratorAggregate, and JsonSerializable methods for PHP 8.1+

CJavascript, CQC, CManager

  • Add missing PHPDoc on CJavascript_Validation_ValidatorJavascript::__get(), CQC::createProcessor(), and CManager_EditorJs::calculateImageClasses()