The following is an instructional guide on how to upgrade your 1.x October CMS installation to the latest version 2.0
Even though this is a major upgrade to the October CMS platform, it mostly affects the configuration file structure and introduces a new editor system in the backend. Most, if not all, of your plugins and themes should still be fully compatible.
We will use an approach that keeps a backup of your old website files in case you need to rollback any changes. However, you should take a snapshot of your database for cases where this needs to be rolled back.
Before proceeding, make sure that you have a license key ready by visiting the Project Management page of the October CMS website.
Table of Contents
- Backing Up The Database
- Database Requirements
- Upgrading from 1.0 or 1.1 to 2.0
- System
- Backend
- Library
- Database
Backing Up The Database
Use this command to backup your MySQL database. For example, if the username is root and the database is called database_name. You will then be prompted to enter the password.
mysqldump -u root -p database_name > october_backup_20210317.sql
To restore the backup, you can use this command.
mysql -u root -p database_name < october_backup_20210317.sql
PHP 7.2.9 Required
The new minimum PHP version is now 7.2.9
Database Requirements
The new minimum supported version for MariaDB is 10.2 and MySQL is 5.7.7, however, older versions will still work. If you wish to continue to use lower versions, ensure the following is added to your database configuration under the key database.connections.mysql
.
'varcharmax' => 191,
See the Laravel issue on why this is necessary.
Upgrading from 1.0 or 1.1 to 2.0
In summary we will do the following:
- Install October CMS 2.0 in a new directory
- Copy the config, storage, plugins and themes to the new directory
- Migrate the database and test the website
- Swap the old directory with the new directory
Convert to environment variables
October CMS now uses environment variables as standard for its configuration. If you do not have a .env
file in your application directory, create one using the following command.
php artisan october:env
Install October CMS in new directory
We will need to prepare a new directory to place the updated version. For example, if your website is located in /var/www/mywebsite then we should place the new installation in /var/www/mywebsite-new by running these commands.
cd /var/www
composer create-project october/october mywebsite-new
To make the configuration process run smoothly, you can copy your old configuration to the new website. This step is optional.
cp mywebsite/.env mywebsite-new/
Copy or move storage
Depending on the size of your storage directory. You can either copy or move the storage directory to the new installation. To copy it across.
cp -R mywebsite/storage mywebsite-new/
If you decide to move it across, you will need to create the new resources folder first. When creating this folder, make sure it has read and write permissions for the web server.
cp -R mywebsite-new/storage/app/resources mywebsite/storage/app
cp mywebsite-new/storage/app/.gitignore mywebsite/storage/app
Then perform the move.
mv mywebsite-new/storage mywebsite-new/storage-old
mv mywebsite/storage mywebsite-new/
Delete the old storage directory.
rm -rf mywebsite-new/storage-old
Next clean up the framework cache files by deleting the following files.
storage/framework/classes.php
storage/framework/packages.php
storage/framework/services.php
Copy themes and plugins
Copy any desired themes from old website to new. In this example we are copying the mytheme theme directory. Repeat the command for any other themes you wish to move.
cp -R mywebsite/themes/mytheme mywebsite-new/themes/
If you have any non-vendor plugins that you have developed yourself, copy them across as well. This example will copy the entire sam author and plugins.
cp -R mywebsite/plugins/sam mywebsite-new/plugins/
Note: If your plugins use composer dependencies or are published to source control, skip this step and follow the instructions for private plugins below.
Perform installation
Change directory to the new website.
cd mywebsite-new
Proceed through the installation process steps by running the installation command.
php artisan october:install
Migrate the database with the migration command.
php artisan october:migrate
Test that October CMS is working properly by opening it in a browser.
php artisan serve
If the demo theme or your theme is displayed, then everything is good.
Sync project and private plugins (optional)
Now install your vendor plugins and themes by syncronising to your project.
php artisan project:sync
If you have developed your own plugins that use composer dependencies, called private plugins, first place them inside a directory anywhere outside of the project. For example, we could place them inside /home/sam/plugins.
Ensure that your private plugins include a composer.json
file with these minimum specification. For example, we will use a plugin named Sam.Blog and it translates to a package name of sam/blog-plugin
.
{
"name": "sam/blog-plugin",
"type": "october-plugin",
"description": "A Great Blog Plugin",
"require": {
"composer/installers": "~1.0"
}
}
Use the plugin install command and direct to a local source. For example, a plugin named Sam.Blog is installed with the following.
php artisan plugin:install Sam.Blog --from=/home/sam/plugins/sam/blog
Alternatively, if your plugin is already published to a source control repository, you can reference this address instead.
php artisan plugin:install Sam.Blog --from=git@github.com:sam/blog-plugin.git
Repeat this process for each private plugin in your website. Then test that everything is working.
php artisan serve
Replace old with new
Finally, complete the website upgrade, replace the old website with the new website.
cd ..
mv mywebsite mywebsite-old
mv mywebsite-new mywebsite
If you are using a public folder in your application, don't forget to mirror to it.
cd mywebsite
php artisan october:mirror
Enjoy using the latest version of October CMS!
System
Configuration Changes
Previously all configuration was stored in the config/cms.php file. Configuration files have been changed so that each core module has its own configuration file. Please observe the following new configuration files.
config/cms.php
config/system.php
config/media.php
config/backend.php
The following configuration keys have been renamed or moved.
Old Value | New Value |
---|---|
cms.backendSkin | backend.skin |
cms.backendUri | backend.uri |
cms.backendForceSecure | backend.force_secure |
cms.backendForceRemember | backend.force_remember |
cms.disablePlugins | system.disable_plugins |
cms.linkPolicy | system.link_policy |
cms.storage | system.storage |
cms.loadModules | system.load_modules |
cms.pluginsPath | system.plugin_asset_url |
cms.themesPath | system.theme_asset_url |
cms.enableCsrfProtection | system.enable_csrf_protection |
cms.convertLineEndings | system.convert_line_endings |
cms.defaultMask | system.default_mask |
cms.restrictBaseDir | system.restrict_base_dir |
cms.updateAuth | system.update_gateway_auth |
cms.activeTheme | cms.active_theme |
cms.enableRoutesCache | cms.enable_route_cache |
cms.urlCacheTtl | cms.url_cache_ttl |
cms.parsedPageCacheTTL | cms.template_cache_ttl |
cms.enableAssetCache | cms.enable_asset_cache |
cms.enableAssetMinify | cms.enable_asset_minify |
cms.enableAssetDeepHashing | cms.enable_asset_deep_hashing |
cms.databaseTemplates | cms.database_templates |
cms.enableSafeMode | cms.safe_mode |
cms.forceBytecodeInvalidation | cms.force_bytecode_invalidation |
cms.enableTwigStrictVariables | cms.enable_twig_strict_variables |
cms.enableBackendServiceWorkers | backend.enable_service_workers |
cms.twigNoCache | cms.enable_twig_cache |
cms.fileDefinitions.* | system.file_definitions |
cookie.unencryptedCookies | system.unencrypt_cookies |
brand.appName | backend.brand.app_name |
brand.tagline | backend.brand.tagline |
brand.secondaryColor | backend.brand.secondary_color |
brand.logoPath | backend.brand.logo_path |
cms.storage.media.ignore | media.ignore_files |
cms.storage.media.ignorePatterns | media.ignore_patterns |
cache.codeParserDataCacheKey | cms.code_parser_cache_key |
cache.disableRequestCache | system.in_memory_cache (reversed) |
Version Checking
A note about backwards compatbility, if you need to check the version of October CMS, you can look for the System
class.
if (class_exists('System')) {
// Running October CMS 2.0
}
else {
// Running October CMS 1.0
}
Project is No Longer Syncronised Automatically
Previously when performing a system update, the platform will check with the server for any new plugins or themes and install them. This forces the website to use all plugins and themes defined by the project. This functionality has changed to decouple this process and the plugins and themes are now defined by the composer.json
file instead.
A new command has been introduced to install anything added to the project recently.
php artisan project:sync
This command will install all plugins and themes defined by the project and add them to your composer file.
Backend
Removed Middleware on Backend Controllers
Previously it was possible to register middleware on any secondary backend controller. This ability has been removed as it introduces significant complexity to the system. The following is no longer possible.
\MeAuthor\MyPlugins\Controllers\Posts::extend(function($controller) {
$controller->middleware(...);
});
As an alternative, it is still possible to register middleware on the primary backend controller.
\Backend\Classes\BackendController::extend(function($controller) {
$controller->middleware(...);
});
For other simpler alternatives, see the article on overriding responses in backend controllers.
Migrations No Longer Occur on Login
Previously the database would be migrated when a user successfully signed in to the backend. This functionality and associated config (cms.runMigrationsOnLogin) has been removed. Migrations are now performed as part of the standard update process.
Controller Methods Should Be Snake Case
Consistency with controller actions has been improved. Previously, when defining a controller action, a URL like /download-pdf
would translate to an action method of downloadPdf
. This logic has changed and segmented action names should use snake_case instead. For example, /download_pdf
or /download-pdf
will reference an action method of download_pdf
.
jQuery Migrate Plugin Removed
The jQuery version in the backend area has been updated to v3 from v2 and the core accomodates all the necessary changes. As a result, the jQuery Migrate plugin is no longer included by default. We recommend following the Upgrade Guide for jQuery 3.0 to ensure your plugins remain compatible.
Library
Database Behaviors are Deprecated
The following classes have been deprecated and will be no longer supplied by the system in a later update.
If your plugins depend on these classes, we recommend taking a copy of these classes and including them locally in your plugin. This should give you greater control over the behavior and its functionality.
Note: The database traits of the same name still exist and should be used where possible.
Migrations No Longer Use Transactions by Default
As a result of PHP 8's implementation of the PDO library, when a commit action is called inside a transaction, an exception will be thrown. Previously when the code encountered a commit action, it would fail silently and commit the transaction, usually unknown to the developer.
As a result of this change, it is not longer possible to apply a general approach to database transactions and it is now up to the developer. We recommend wrapping migrations or seed scripts in a transaction, especially if they involve multiple changes.
Db::transaction(function() {
// Place code in here
});
This approach is more explicit and gives more control over the database processes.
Removed Helper Paths
The uploads_path()
and media_path()
global functions have been removed. These functions were found to be unreliable for use as system methods since objects can be stored using external providers and won't always exist on disk.
If your code relies on these functions, you may use a replacement as following.
// media_path()
storage_path('app/'.config('system.storage.media.folder', 'media'));
// uploads_path()
storage_path('app/'.config('system.storage.uploads.folder', 'uploads'));
Unsafe eval reduced in AJAX Framework
The unsafe command eval()
has been removed from the AJAX framework data attributes. Please check if your code is using these attributes and adapt the code accordingly.
- data-request-before-update
- data-request-success
- data-request-error
- data-request-complete
The primary argument available is this
similar to the onclick
JavaScript attribute. To create the $el
argument, use $(this)
instead. The data
argument is also still available but we recommend passing to a function that uses the JavaScript API instead. This is because the feature will eventually be phased out.
Internal Caching Removed on Models
The internal cache used by Eloquent and Halcyon models has been removed to reduce the memory footprint of the application. As a result the following property has been removed from database models.
/**
* @var bool Indicates if duplicate queries from this model should be cached in memory.
*/
public $duplicateCache = true;
Database
Attachments and Deferred Records Only Support Integer Keys
This section is required for PostgreSQL databases and an optional patch for MySQL and other database engines. We recommend all platforms apply this patch as it has a signifant improvement to the platform performance.
The following tables now use integer keys:
Table | Column |
---|---|
deferred_bindings |
slave_id |
system_files |
attachment_id |
Previously these tables allowed strings to be used as keys and this carried an 800% performance penalty that was noticably slow at scale. This approach was intended to support both UUID (string) and ID (integer) primary keys. The support for UUIDs has now been dropped and related tables should introduce integer keys in addition to their UUID counterparts.
A migration function has been introduced to safely switch to integer keys whilst retaining the string key values. We strongly recommend taking a database backup before running this command.
php artisan october:util patch 2.0
This will perform the following steps for both tables:
- Rename the string column to a str_column (eg:
attachment_id
becomesstr_attachment_id
) so the existing values are not lost - Introduce the new integer column (
attachment_id
) - Copy values from the string column to the integer column, where possible
- If a string is found that cannot cast to integer (i.e a UUID), a warning is displayed with a list of records that need to be attended to.
This optimization is not required for new installations.