Upgrading your October CMS 1.0 to the latest 3.0 Version

Periodically updating October CMS is a good idea with each new released version taking advantage of bug fixes and new features. First step to be taken is #backup of your #site before upgrading. Reason being possibility of experience difficulties with third party #extensions compatiblity with Latest version.

In summary we will do the following:

    * Setup #testing environment for upgrade and restore the backup copy of your site in staging folder, else under a #subdomain.
    * 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

Installing latest Version of October CMS

    * Downloads latest version at the top by click "Download" to save the zip version. Unzip the zip file to staging folder location for ease.

    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/myoctobercmssite then we should place the new installation in /var/www/myoctobercmssite-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.

    • October\Rain\Database\Behaviors\Purgeable - link
    • October\Rain\Database\Behaviors\Sortable - link

    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:

    1. Rename the string column to a str_column (eg: attachment_id becomes str_attachment_id) so the existing values are not lost
    2. Introduce the new integer column (attachment_id)
    3. Copy values from the string column to the integer column, where possible
    4. 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.