Winter v1.2.1 is now available

Ben Thomson
Posted on Oct 19, 2022.

The Winter CMS maintainers are pleased to announce that Winter CMS v1.2.1 is now available. You may upgrade to this version automatically by running a Composer update in your Winter CMS install directory through composer update.

The main focus of this release was improving support for more complex hosting solutions such as Laravel Vapor or Amazon Web Services that use ephemeral microservices, proxying and cloud storage, meaning less configuration and customisation in order to run Winter CMS on SaaS platforms. In addition, we refined our API to follow Laravel 9 more closely and fixed several bugs that had been reported from the v1.2.0 release.

UX/UI Improvements

  • Added support for streaming file uploads directly to S3 storage disks via the stream_uploads option on the disk configuration. Requires the Winter.DriverAWS plugin.
  • Added support for the data-request-parent attribute to the AJAX framework, allowing AJAX requests to include the data from the elements that spawned them which allows for highly complex workflows where popups spawn popups and then those popups need to call their own AJAX handlers but the page previously didn't know to initialize them without their parent data being present. This fixes support of the RecordFinder inside of popups like the RelationController's update & pivot forms as well as the FileUpload's description form popup inside of other popups.
  • Switched the winter:up / migrate commands to use the new Laravel CLI components for improved output formatting.
  • Added support for type: range Form fields.
  • Added support for the conditions property on List Columns with a relationship defined via the relation property.
  • Added support for changing an image's extension / file type when using the ImageResizer to resize the image.
  • Added support for ignoring specific Mix packages to avoid including third-party Mix packages in your application's package.json unnecessarily.
  • Clicking the label of a switch field will now toggle the switch.
  • Increased the width of the crop dimension inputs when cropping or resizing an image in the Media widget.
  • Standard HTML flash messages that are converted to JavaScript flash messages through Snowboard are now removed once converted, to prevent the original message from remaining even after the flash message is dismissed.
  • The autogenerated password for the default administrator account is now displayed in the winter:install command output and can be changed through the wizard.
  • Documented app.tempPath configuration option.
  • Added winter:password as an alias for winter:passwd.
  • Minor CSS improvements.

API Changes

  • Removed the default maxlength of 255 from type: text Form fields.
  • The twig.environment.cms Twig environment is no longer provided as a singleton, instead being generated on each request to App::make(). This helps to avoid conflicts when calling the CMS controller multiple times in the same request.
  • Deprecated the Winter\Storm\Database\Behaviors\Purgeable behavior as the Purgeable trait is now included by default on all Winter models.
  • Added the backend.formwidgets.fileupload.onUpload event to allow for custom handling of file uploads in the FileUpload FormWidget.
  • Added the backend.widgets.uploadable.onUpload event to allow for custom handling of file uploads in the widgets that implement the Backend\Traits\UploadableWidget trait.
  • Added the formwidgets.fileupload.initUploader Snowboard global JS event to allow for interacting with the FileUpload's JS uploader instance.
  • Added the formwidgets.richeditor.init Snowboard global JS event to allow for interacting with the RichEditor's JS editor instance.
  • Added the widgets.mediamanager.initUploader Snowboard global JS event to allow for interacting with the MediaManager's JS uploader instance.
  • Switched visibility of getRelationModel() from protected to public on the Backend\Traits\FormModelWidget trait.
  • Switched visibility of getOptionsFromModel() from protected to public on the Backend\Widgets\Form widget.
  • Added the following methods to the Backend\Traits\UploadableWidget trait to make it easier to customize upload behaviour:
    • uploadableGetDisk()
    • uploadableGetUploadPath()
    • uploadableGetUploadUrl()
  • Added the following model relation events:
    • model.relation.beforeAdd($relationName, $relatedModel)
    • model.relation.afterAdd($relationName, $relatedModel)
    • model.relation.beforeRemove($relationName, $relatedModel)
    • model.relation.afterRemove($relationName, $relatedModel)
    • model.relation.beforeAssociate($relationName, $relatedModel)
    • model.relation.afterAssociate($relationName, $relatedModel)
    • model.relation.beforeDisassociate($relationName)
    • model.relation.afterDisassociate($relationName)
  • A new mix:run Artisan command has been added to allow scripts defined in the package.json file of a Mix package to be run easily through the CLI. You can find the documentation here.
  • The AJAX framework and Snowboard framework now both enforce either a class name dot (.) or an ID hash (#) to be prefixed to any partials that are to be updated in an AJAX response. This includes any mapped selectors.
  • Snowboard JavaScript AJAX requests now accept two or three parameters, similar to the old framework. When using two parameters, the user only needs to specify the handler and options - it is assumed in this case that the AJAX requests is detached and not tied to an element.
  • Added Winter\Storm\Database\Traits\HasSortableRelations trait to make it easier to sort related records on a model.
  • Added support for ** as a wildcard when setting the application's trusted proxies. This was originally supported in fideloper/trustedProxy but was removed without explanation in Laravel 5.6. * will trust the currently requesting IP address, ** will trust all proxies in a chain of proxies (often required if you are behind something like CloudFront and another proxy). This was required for retrieving the correct Client IP address when using Laravel Vapor.
  • Properties added to Model instances via addDynamicProperty() are now automatically added as purgeable attributes to prevent them from being saved to the database.
  • Added the Arr::moveKeyToIndex($array, $targetKey, $index) helper method to make it easier to move a specific array element to the specified index.
  • Added the Str::unique($str, $items, $separator, $step) helper method that ensures the provided string will be unique when compared to the provided array by adjusting the string with the separator & step as necessary. Useful for filename deplication or other deduplication of unique references.
  • Added the Str::join($items, $glue, $lastGlue, $dyadicGlue) helper method to join an array of items with a glue string, optionally using a different glue string for the last item and for the dyadic item case (only two items). By default this applies the "Oxford / Serial Comma" gramatical construct when listing items.
  • Added the fromStorage() helper method to the Winter\Storm\Database\Attach\File model class in order to create a new file record from a file path that already exists on the file model's storage disk.
  • Added new Winter\Storm\Console\Traits\HandlesCleanup trait to the base Winter Command class that makes it easier to implement cross-platform cleanup logic on your CLI commands when process termination signals are received.
  • Added support for root level paths in the Halcyon DbDatasource, required for Child Theme support.
  • Added support for exit codes in mix:compile. Also added support for the --silent, --stop-on-error, and --manifest flags.

Bug Fixes

  • The winter:test command now automatically uses the correct bootstrap file for unit testing, irrespective of the bootstrap configuration in any plugin or module's phpunit.xml file, to assist users migrating their unit tests to Winter 1.2.
  • Fixed issue where plugins weren't being correctly sorted by their dependencies when depending on a plugin that registers itself as a replacement which could cause migrations to run in the incorrect order.
  • Fixed typo in the MediaManager widget that was preventing SVGs from displaying their previews in the sidebar.
  • Fixed issue when attempting to generate a TailwindCSS theme scaffold on a case sensitive file system.
  • Fixed mismatching method signature on AutoDatasource->lastModified() that could cause issues when using DatabaseTemplates in v1.2.
  • Fixed issue where MorphedByMany relationships would use the wrong class name when building queries.
  • Removed an override to the Input::all() facade method, which prevented files from being included in the result, breaking previous behaviour.
  • Removed an extra 0 that was left over in numberrange filter partials.
  • Fixed an issue where only the last component would be saved in a CMS template due to the framework not correctly processing arrayed POST data.
  • Fixed an issue with the winter:fresh command where the demo plugin was not removed and an error message was shown.
  • The Array Source trait will no longer attempt to save a temporary SQLite DB if storage is disabled via setting $cacheArray to false.
  • Fixed an issue where custom AJAX error responses were being mangled by the Snowboard Request class, before sending off to the error handlers. If an error does not appear to be a PHP exception with an exception class and message, it will now pass through the response untouched (but still be considered an error response).
  • Fixed an issue where the File model's fromUrl() method would not correctly determine the file's mimeType if the file was delivered with a Content-Type header that was incorrectly capitalized.
  • Fixed an issue where migrations using anonymous classes could not be run more than once in a single process.
  • Fixed support for the Laravel ClassName@method syntax for event listeners.
  • Fixed issue where custom pivot models were not being used when using the attach method on a BelongsToMany relationship.
  • Fixed support for queueing emails (was broken by a change in Laravel 7 that was missed in the Winter v1.2 upgrade).
  • Fixed support for hidden files in Zip folders on systems without support for GLOB_BRACE (Solaris, Alpine Linux, etc).
  • Fixed issue that occurred when attempting to dynamically add HasOneThrough|HasManyThrough relations to models.
  • Improved support for Winter < v1.2 mail configurations.
  • Fixed breaking change in Laravel 9.36 with the Winter\Storm\Console\Command's alert() method.
  • Fixed issue with identifying currently installed versions of plugins when the versions reported by the filesystem do not match exactly (i.e. with or without the "v" prefix) the versions reported by the database.
  • Fixed issue where Snowboard assets loaded via the {% snowboard %} Twig tag were not taking into account the configured app.asset_url of the application.
  • Fixed issue where the Status backend Dashboard Widget would break on clean installs.
  • Improved the reliability of the System's first boot date by storing it as a system parameter instead of relying on the oldest present plugin.
  • Fixed an issue where migrations were not ran if a notes output instance is not available to the migrator.
  • Fixed an issue where attempting to crop images with unsafe characters in their path would fail.
  • Fixed support for Winter Mix commands on Windows.
  • Fixed an issue where attempting to crop / resize images that were bigger than the viewport window would fail when using the TailwindUI backend skin.
  • Fixed issue when attempting to preview a CSV column with the ImportExportController behavior.
  • Fixed issue where the codeeditor and richeditor fields were not properly triggering change events when their contents were changed.
  • Fixed issue where custom error messages sent via AJAX and processed by Snowboard would not be properly handled.
  • Fixed issue where the jobs / failed_jobs table structure did not match that of Laravel 9.

Security Improvements

  • Prototype hardening has been implemented on the Snowboard framework to prevent prototype pollution. You may read the security advisory for more information.
  • Fixed issue where the AuthManager's persistence cookie was not respecting the configuration values set in config/session.php.
  • Added a new Svg helper class to make it easier to work with SVG files. Currently one method (extract()) is available which sanitizes and optionally minifies the provided SVG file making it safer to deal with.
  • Added migrate to the list of commands that require plugins to have the $elevated property set in order to run when the command is being run.

Translation Improvements

  • Fixed a misnamed language string for the custom editor HTML styles input.
  • Improved German translation.
  • Improved Vietanamese translation.
  • Improved Ukrainian translation.
  • Improved Russian translation.

Performance Improvements

  • Slightly optimised searching for used slugs with models using the Sluggable trait by runnning an "exists" query as opposed to a "count" query.

Community Improvements

  • The Winter CMS module sub-split is now automated, ensuring that the module repositories are now automatically updated with the latest changes as soon as they are committed to the main repository.
  • The base System\Tests\Bootstrap\PluginTestCase class has been signficantly refactored to improve testing in plugins. While it is mostly backwards-compatible, the method runPluginRefreshCommand is now deprecated and will be removed in the Winter CMS 1.3 branch. Please use the instantiatePlugin method instead if you have overridden the core plugin test case methods.


  • Moved the Laravel configuration file writing functionality out of the Winter\Storm library and into it's own standalone Winter\LaravelConfigWriter library. This was done in order to reuse it in the web installer, but also means that any Laravel application can take advantage of this package.
  • Made the Composer merge plugin less greedy by default, previously it would merge in all plugin composer.json files that existed in your project, now it will only merge in specific plugin paths defined in your project's composer.json. Copy the changes from GitHub in order to apply it to your projects.


Keep informed

Sign up to our newsletter and receive updates on Winter releases, new features in the works, plugin and theme promotions and much more!