5.12.0 (2026-04-29)
Changed
- Changed
Phalcon\Assets\Managerfilter type check fromis_object()totypeofand updated the error message to"The filter is not valid"#16889 - Changed
Phalcon\Cache\AbstractCache::doDeleteMultiple()to delegate to the storage adapter'sdeleteMultiple()instead of looping over individualdelete()calls #16859 - Changed
Phalcon\Di\Exceptionmessage for missing services from"was not found in the dependency injection container"to"is not registered in the container"#16889 - Changed
Phalcon\Di\Service\Buildererror messages for service parameters to use double quotes instead of single quotes #16889 - Changed
Phalcon\Forms\Element\AbstractElement::getLocalTagFactory()to throwPhalcon\Forms\Exceptioninstead of silently creating a newTagFactorywhen neithersetTagFactory()nor a parentFormprovides one #16894 - Changed
Phalcon\Forms\Element\Select::render()to useTagFactory-basedHtml\Helper\Input\Selectinstead of the deprecatedPhalcon\Tag\Select#16894 - Changed
Phalcon\Html\TagFactoryto accept an optionalResponseInterfacein the constructor (useful forpreload) #16892 - Changed
Phalcon\Mvc\ControllerandPhalcon\Mvc\View\Engine\AbstractEngineto be events aware #16890 - Changed
Phalcon\Mvc\View\Engine\Volt\Compiler::setOptionsto return$thisnow #16891 - Changed calls to
globals_getandglobals_setin the code withPhalcon\Support\Settings::get()/set()#16884 - Changed exception messages across multiple components to use
"does not"instead of"doesn't"for consistency #16889
Added
- Added
Phalcon\Encryption\Security\Uuidfactory and versioned adapters (Version1–Version7) with aUuidInterfacecarrying standard RFC 4122 namespace constants; each version is a singleton cached by the factory, invoked viav1()–v7()#16326 - Added
Phalcon\Html\Helper\FriendlyTitle- available viaTagFactoryasfriendlyTitle[#16892(https://github.com//issues/16892) - Added
Phalcon\Html\Helper\Input\Select::fromData()to populate select options from aSelectDataInterfaceprovider, with optgroup support #16894 - Added
Phalcon\Html\Helper\Input\Select\SelectDataInterface,Phalcon\Html\Helper\Input\Select\ArrayData, andPhalcon\Html\Helper\Input\Select\ResultsetDataas data providers for theSelecthelper #16894 - Added
Phalcon\Html\Helper\Preload- available viaTagFactoryaspreload;TagFactorynow accepts an optionalResponseInterfaceas its third constructor parameter [#16892(https://github.com//issues/16892) - Added
Phalcon\Mvc\Model\Resultset::refresh()to re-execute the underlying query and update the resultset with fresh data from the database #16409 - Added
deleteMultiple()toPhalcon\Storage\Adapter\*to delete multiple keys in a single operation using native batch capabilities per adapter #16859 - Added key validation per entry in
Phalcon\Cache\AbstractCache::doDeleteMultiple()throwingInvalidArgumentExceptionfor keys containing invalid characters #16859 - Added named static factory methods
Phalcon\Forms\Exception::tagFactoryNotFound()andPhalcon\Forms\Exception::usingParameterRequired()#16894
Fixed
- Fixed
Phalcon\Db\Dialect\Postgresql::modifyColumn()to generate correct SQL when changing a boolean column's default value: replacedemptycheck withhasDefault()to avoid treatingfalseas "no default", removed the boolean-only branch that omitted theALTER TABLEprefix, and fixedcastDefault()to return PostgreSQL literalstrue/falseinstead of raw PHP booleans #15829 - Fixed
Phalcon\Db\Result\PdoResult::$rowCountto usenullas the uninitialised sentinel instead offalse, preventing a count of0rows being confused with "not yet counted" #16409 - Fixed
Phalcon\Dispatcher\AbstractDispatcher::dispatch()to refresh the localeventsManagerandhasEventsManagervariables afterinitialize()returns, so that an events manager attached to the dispatcher insideinitialize()is honoured for all subsequent dispatch events (afterInitialize,afterExecuteRoute,afterDispatch,afterDispatchLoop, etc.) #16440 - Fixed
Phalcon\Filter\Validation::bind()to skip the dependency injection container lookup whendatais empty, preventing unnecessaryDi\Exceptionerrors #16889 - Fixed
Phalcon\Filter\Validation\AbstractValidator::allowEmpty()to support a value-list array (e.g.[null, '']) in addition to the per-field map syntax, using strict===comparison so that'0'is never silently treated as empty #15491 - Fixed
Phalcon\Filter\Validation\AbstractValidator::messageFactory()to pass the joined field string toPhalcon\Messages\Messageinstead of the raw array when multiple fields are provided #16889 - Fixed
Phalcon\Filter\Validation\Validator\Alpha::validate()to returnfalsewhenallowEmptyis explicitly set tofalseand the submitted value isnullor an empty string #16200 - Fixed
Phalcon\Forms\Form::isValid()to apply field filters even when no validators are specified (again) #16830 - Fixed
Phalcon\Html\Escaper::css()andPhalcon\Html\Escaper::js()to return an empty string instead offalsewhen the input is empty or contains only a null codepoint #16889 - Fixed
Phalcon\Html\Helper\AbstractHelper::renderAttributes()to emit boolean HTML5 attributes (e.g.async,defer) as standalone attribute names instead ofasync="1"when the attribute value istrue#16304 - Fixed
Phalcon\Html\Helper\Breadcrumbsto support subdirectory installs: addedgetPrefix()/setPrefix()for a manual string prefix, and an optionalUrlInterfaceconstructor parameter that resolves links throughurl->get()(including base URI prepending and double-slash normalisation);TagFactoryaccepts an optional fourthUrlInterfaceargument and passes it toBreadcrumbsautomatically #14957 - Fixed
Phalcon\Http\Response::setStatusCode()exception message from"Non-standard statuscode given without a message"to"Non-standard status-code given without a message"#16889 - Fixed
Phalcon\Image\Adapter\AbstractAdapter::crop()to correctly handleoffsetX = 0andoffsetY = 0by changing the parameter types frominttovar; the previousinttyping caused Zephir to compile thenullcheck as0 == offsetin C, making explicit zero offsets indistinguishable from omitted (center) offsets #16156 - Fixed
Phalcon\Image\Adapter\Gd::processResize()to preserve PNG alpha channel transparency by replacingimagescale()withimagecreatetruecolor()+imagealphablending(false)+imagesavealpha(true)+imagecopyresampled()#16316 - Fixed
Phalcon\Image\Adapter\Imagick::processPixelate()to explicitly cast division result tointto prevent implicit float-to-int deprecation #16889 - Fixed
Phalcon\Mvc\Model::__get()to return the already-loaded related record instead of re-fetching from the database, preventing modifications to relation properties from being discarded #15554 - Fixed
Phalcon\Mvc\Model::__unserialize()andPhalcon\Mvc\Model::unserialize()to callonConstruct()after deserialization, so typed properties initialized inonConstructare correctly set when a model is restored from cache #15906 - Fixed
Phalcon\Mvc\Model::__unserialize()andPhalcon\Mvc\Model::unserialize()to restore snapshot as the current attributes (instead of null) when a model is deserialized with no pending changes, preventinggetChangedFields()from throwing after cache retrieval #15837 - Fixed
Phalcon\Mvc\Model::cloneResultMap()to call model setter methods (e.g.setName()) during ORM hydration whenorm.disable_assign_settersisfalse, making hydration behaviour consistent withassign(); setters inlocalMethods(Phalcon internals) are excluded #14810 - Fixed
Phalcon\Mvc\Model::collectRelatedToSave()to skip unmodifiedhasOne/hasManyrelated records that have snapshot data, preventing spuriousINSERT/UPDATEstatements when a relation is read but not changed #16000 - Fixed
Phalcon\Mvc\Model::doLowInsert()to also resetuniqueKey(in addition touniqueParams) after an auto-increment INSERT so that a subsequenthas()call on the same record rebuilds the primary-key condition from current attribute values; previously,uniqueParamswas cleared butuniqueKeywas kept, causinghas()to query with anullparameter and returnfalse, which madeSoftDeleteattempt to INSERT an already-existingbelongsTorelated record instead of updating it #16453 - Fixed
Phalcon\Mvc\Model::doLowUpdate()to skip columns whose string value matches the column's function-call DB default (e.g.gen_random_uuid()) in the non-dynamic update path, preventing the function name from being passed as a bound string parameter and causing a DB type error #15828 - Fixed
Phalcon\Mvc\Model::doSave()to capture the model snapshot before the INSERT/UPDATE and restore it whenpostSaveRelatedRecordsfails and rolls back the transaction; previously, withorm.update_snapshot_on_saveenabled, the snapshot was permanently updated insidedoLowInsert/doLowUpdateeven when the transaction was rolled back, causing Dynamic Update to silently skip the write on the next save attempt #16410 - Fixed
Phalcon\Mvc\Model::getRelated()to return already-fetched relations from the internal cache (dirtyRelatedfirst, thenrelated) instead of always querying the database; cache is cleared aftersave()anddelete()to prevent stale results #16409 - Fixed
Phalcon\Mvc\Model::toArray()to catchErrorthrown by a getter that accesses an uninitialized typed PHP property (can occur whencloneResultMap()skips a null value for aNOT NULLcolumn, e.g. via aLEFT JOIN), returningnullinstead of propagating the error #15711 - Fixed
Phalcon\Mvc\Model::unserialize()to catchTypeErrorwhen assigning a serialisednullback to a typed non-nullable PHP property, preventing a crash on the second request when the model is loaded from a cache like APCu #15711 - Fixed
Phalcon\Mvc\Model\Manager::getRelationRecords()to apply reusable caching forhasManyToManyandhasOneThroughrelations;reusable: truewas previously ignored for through-relations #15934 - Fixed
Phalcon\Mvc\Model\Query::executeSelect()to embedPhalcon\Db\RawValuebind parameters directly in the SQL string instead of passing them to PDO #16350 - Fixed
Phalcon\Mvc\Model\Query::executeSelect()to use the write connection when the query contains aFOR UPDATEclause, instead of always using the read connection #16032 - Fixed
Phalcon\Mvc\Model\Query::getExpression()to emitNOT BETWEENinstead ofBETWEEN NOTfor thePHQL_T_BETWEEN_NOTtoken, producing valid SQL #16812 - Fixed
Phalcon\Mvc\Model\Query::getSelectColumn()to use the full model class name as thebaliaskey in a complex resultset when the model is namespaced (e.g.App\Models\Users), instead of incorrectly applyinglcfirst()to the fully-qualified name; non-namespaced models (e.g.Robots) retain the existinglcfirst()behaviour (robots) #16052 - Fixed
Phalcon\Mvc\Model\Query\Builder::getPhql()to use a named bind parameter (:APK0:) instead of embedding the raw primary-key value in the PHQL string whenfindFirst()is called with a numeric or numeric-string argument; this prevents unbounded growth of the internal PHQL AST cache (Query::$internalPhqlCache) in long-running CLI processes #14656 - Fixed
Phalcon\Mvc\Model\Resultset\Complex::current()to returnnullinstead of an empty model instance when aLEFT JOINproduces no matching row (all column values arenull) #16239 - Fixed
Phalcon\Mvc\Model\Transaction\Manager::collectTransaction()to keep the correct transactions when rebuilding the list after removal #16522 - Fixed
Phalcon\Mvc\Model\Transaction\Manager::commit()to remove each transaction from the pool after committing so that subsequentget()calls return a fresh transaction #16522 - Fixed
Phalcon\Mvc\Modelto handle the `lastInsertId correctly under Postgres #16920 #16436 #15775 - Fixed
Phalcon\Mvc\Router\Annotations::handle()to strip thecontrollerSuffixfrom the class name when a fully-qualified class name already includes it (e.g.App\Controllers\InvoicesController), preventing the doubled suffixInvoicesControllerController#16238 - Fixed
Phalcon\Paginator\Adapter\QueryBuilder::paginate()to correctly count groups whengroupBy()receives a multi-column array, using aSELECT DISTINCTsubquery instead of the PostgreSQL-incompatibleCOUNT(DISTINCT col1, col2)form #15912 - Fixed
Phalcon\Paginator\Adapter\QueryBuilder::paginate()to use thecolumnsoption as theCOUNT(DISTINCT ...)argument when aGROUP BYis present, allowing NULL-safe expressions to be supplied #15266 - Fixed
Phalcon\Storage\Adapter\Libmemcached,Phalcon\Storage\Adapter\RedisandPhalcon\Storage\Adapter\Weakto callinitSerializer()during construction #16889 - Fixed
Phalcon\Storage\Adapter\Redisto initializelifetimefrom options during construction #16889 - Fixed
Phalcon\Support\Helper\Json\Encodeto prefix theInvalidArgumentExceptionmessage with"json_encode error: "for consistency #16889 - Fixed the CI run to correctly use updated changes, and reuse artifacts #16920
- Fixed the CI run to now run Postgresql tests #16920
- Fixed the CI run to now run Sqlite tests #16920