Edit on GitHub

Upgrading Pimcore from Version 5 to Version 6.0

Important things to check and consider prior the update

  • PHP >=7.2 is required
  • IE11 is not officially supported anymore. That doesn't mean that IE11 won't work anymore straight away (although a warning will be shown on login), but that's not guaranteed anymore for the entire lifecycle of v6.
  • Symfony 4 is the default version used by Pimcore 6, if you'd like to stay on the current LTS version of Symfony (3.4), please add the following to your project-specific composer.json: "symfony/symfony": "^3.4.17"

Preparatory Work

IMPORTANT CHANGES PRIOR THE UPDATE!

Adapt your composer.json BEFORE the update!

Due to the removal of sensio/distribution-bundle it's necessary to update your projects composer.json.

To do so, just replace the following lines in your existing composer.json file:

    "post-install-cmd": [
      "Pimcore\\Composer::postInstall",
      "@symfony-scripts"
    ],
    "post-update-cmd": [
      "Pimcore\\Composer::postUpdate",
      "@symfony-scripts",
      "Pimcore\\Composer::executeMigrationsUp"
    ],
    "pre-package-update": [
      "Pimcore\\Composer::prePackageUpdate"
    ],
    "symfony-scripts": [
      "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
      "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
      "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
      "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
    ]     

with the following configuration:

    "post-install-cmd": [
      "Pimcore\\Composer::postInstall",
      "@pimcore-scripts"
    ],
    "post-update-cmd": [
      "Pimcore\\Composer::postUpdate",
      "@pimcore-scripts",
      "Pimcore\\Composer::executeMigrationsUp",
      "@pimcore-scripts"
    ],
    "pimcore-scripts": [
      "Pimcore\\Composer::clearCache",
      "Pimcore\\Composer::installAssets"
    ]

Add database config file /app/config/local/database.yml BEFORE the update!

Database settings were moved to doctrine bundle's default configuration structure (Symfony config-tree), so it is important to create a database.yml with your DB connection values manually before running the update, see also #3268

doctrine:
    dbal:
        connections:
            default:
                user: username
                password: password
                dbname: dbname
                host: host
                port: 3306

Alternatively you can add the database configuration directly to your project's config.yml or any other loaded config file.

Update your web/app.php

Update your web/app.php to the latest available version here: https://raw.githubusercontent.com/pimcore/skeleton/master/web/app.php

Update your Config

If your're using pimcore_admin.dataObjects in your config, please rename dataObjects to objects.

Overview of Changes

General Changes

  • Removed support for Zend_Paginator_Adapter_Interface and Zend_Paginator_AdapterAggregate on listing classes use the Zend Framework 2/3 classes instead
  • Removed support for Zend_Date, use Carbon\Carbon instead
  • sensio/generator-bundle has been removed in favour of Symfony 4. You can still use pimcore:generate:bundle command to generate Pimcore Bundle Skeleton.
  • twig/twig dependency was changed from ^2.0 to ^2.4
  • sensio/distribution-bundle has been removed.
  • Image Thumbnails: removed the option svgPlaceholder, use lowQualityPlaceholder instead.
  • Maintenance Job: Removed event pimcore.system.maintenance and the old way using Job to add custom tasks. Please instead register the maintenance task as a service
  • Pimcore 4 Compatibility Bridge / Legacy Mode is not supported anymore
  • Methods getChilds(), setChilds(), hasChilds() and hasNoChilds() are removed from all ElementInterface classes, use the *Children() equivalents instead
  • Google Analytics tracking using Pimcore\Google\Analytics is not possible anymore
  • bundles/pimcorecore/js/targeting.js is now loaded asynchronously - if you have depending custom code you probably have to adapt it
  • For all Listing classes it's not necessary anymore to call the load() method before calling the actual getter for the items
  • The data properties of all Listing classes are now protected instead of public
  • Commands need to be registered as services and tagged with the console.command tag.
  • System Settings are now stored as Symfony Config, located in var/config/system.yml - if you are using environment specific config files such as system_stage.php you have to migrate them manually.
  • Removed internal feature toggle system: Pimcore\FeatureToggles\*

Data Object Changes

  • Checkbox data-type is tri-state from now on (null, true, false). A default value can be set for the editmode (not on database-level). Null means that inheritance is enabled, otherwise it isn't. Until now, inheritance was enabled also for false value.
  • Removed the Persona and Persona Multiselect data object data-types, please use TargetGroup and TargetGroupMultiselect instead
  • Pimcore\Model\DataObject\Concrete::getValueFromParent() and Pimcore\Model\DataObject\Objectbrick\Data\AbstractData::getValueFromParent throws an InheritanceParentNotFoundException if it can't get a value from a parent
  • Getter hook preGetValue() requires now the use of Pimcore\Model\DataObject\PreGetValueHookInterface, all your classes using preGetValue() need to implement this interface.
  • Namespace Pimcore\Model\Object is not supported anymore, use Pimcore\Model\DataObject instead
  • Custom object data-types must implement interfaces (CustomResourcePersistingInterface, QueryResourcePersistenceAwareInterface and ResourcePersistenceAwareInterface)

Removed Classes, Interfaces, Methods, Constants, Functions, Aliases

is_includeable()
Pimcore\FeatureToggles\*
Pimcore\Google\Analytics
Pimcore\Http\Context\PimcoreContextResolverAwareInterface
Pimcore\Bundle\CoreBundle\EventListener\Frontend\AbstractFrontendListener
Pimcore\Bundle\CoreBundle\EventListener\AbstractContextAwareListener
Pimcore\Model\DataObject\ClassDefinition\Data\Persona
Pimcore\Model\DataObject\ClassDefinition\Data\Personamultiselect
Pimcore\Model\Tool\Targeting\Persona
Pimcore\Model\Tool\Targeting\Persona\Listing
Pimcore\Cache::addClearedTag()
Pimcore\Model\Document\Page\Dao::hasPersonaSpecificElements()
Pimcore\Model\Document\Page::getKeywords()
Pimcore\Model\Document\Page::setKeywords()
Pimcore\Model\Document\Page::setPersonas()
Pimcore\Model\Document\Page::getPersonas()
Pimcore\Model\Document\Page::getPersonaElementPrefix()
Pimcore\Model\Document\Page::getPersonaElementName()
Pimcore\Model\Document\Page::setUsePersona()
Pimcore\Model\Document\Page::getUsePersona()
Pimcore\Model\Document\Page::PERSONA_ELEMENT_PREFIX_PREFIXPART
Pimcore\Model\Document\Page::PERSONA_ELEMENT_PREFIX_SUFFIXPART
Pimcore\Config::DEFAULT_ENVIRONMENT
Pimcore\Document\Newsletter\AddressSourceAdapter\DefaultAdapter::addPersonaConditions()
Pimcore\Version::getBuildDate()
Pimcore\Tool::isFrontentRequestByAdmin()
Pimcore\Model\Version::cleanHistory()
Pimcore\Model\Version\Dao::getOutdatedVersionsSteps()
Pimcore\Model\Version\Dao::getOutdatedVersionsDays()
Pimcore\Model\Version\Dao::disableSlowQueryLog()
Pimcore\Model\Version\Dao::enableSlowQueryLog()
Pimcore\Model\DataObject::preGetValue()
Pimcore\Model\DataObject\ClassDefinition::addNewDataField()
Pimcore\Model\DataObject\ClassDefinition::removeExistingDataField()
Pimcore\Model\Translation\AbstractTranslation::getDate()
Pimcore\Event\SystemEvents::MAINTENANCE
Pimcore\Event\System\MaintenanceEvent
Pimcore\Model\Schedule\Manager\Procedural
Pimcore\Model\Schedule\Maintenance\Job
Pimcore\Maintenance\CallableTask
Pimcore\Model\Document\Tag\Block::enumerate()
Pimcore\Model\Document\Hardlink::setChildsFromSource()
Pimcore\Model\Document\Hardlink::getChildsFromSource()
Pimcore\Model\Document\Page::getName()
Pimcore\Model\Document\Page::setName()
Pimcore\Model\Document\Link::getName()
Pimcore\Model\Document\Link::setName()
Pimcore\Model\Document\Link::getParameters()
Pimcore\Model\Document\Link::setParameters()
Pimcore\Model\Document\Link::getAnchor()
Pimcore\Model\Document\Link::setAnchor()
Pimcore\Model\Document\Link::getTitle()
Pimcore\Model\Document\Link::setTitle()
Pimcore\Model\Document\Link::getAccesskey()
Pimcore\Model\Document\Link::setAccesskey()
Pimcore\Model\Document\Link::getRel()
Pimcore\Model\Document\Link::setRel()
Pimcore\Model\Document\Link::getTabindex()
Pimcore\Model\Document\Link::setTabindex()
Pimcore\Model\Document\Link::getTarget()
Pimcore\Model\Document\Link::setTarget()
Pimcore\Model\Tool\Targeting\Rule::fireEvent()
Pimcore::addToGloballyProtectedItems()
Pimcore::removeFromGloballyProtectedItems()
Pimcore\Placeholder::setWebsiteClassPrefix()
Pimcore\Placeholder::getWebsiteClassPrefix()
Pimcore\Placeholder::setPlaceholderPrefix()
Pimcore\Tool::clearSymfonyCache()
Pimcore\Tool::getSymfonyCacheDirRemoveTempLocation()
Pimcore\Update
Pimcore\Db\ConnectionInterface::supportsParameters()
Pimcore\Db\PimcoreExtensionsTrait::supportsParameters()
Pimcore\Cache\Pool\Redis\Connection
Pimcore\Model\Document\Tag\Area\AbstractArea::_getParam()
Pimcore\Model\Document\Tag\Area\AbstractArea::_getAllParams()
Pimcore\Model\Tool\Email\Log::getToAsArray()
Pimcore\Model\Tool\Email\Log::getCcAsArray()
Pimcore\Model\Tool\Email\Log::getBccAsArray()
Pimcore\Model\Tool\Email\Log::getReplyToAsArray()
Pimcore\Model\Document\Email::getToAsArray()
Pimcore\Model\Document\Email::getAsArray()
Pimcore\Model\Document\Email::getFromAsArray()
Pimcore\Model\Document\Email::getReplyToAsArray()
Pimcore\Model\Document\Email::getCcAsArray()
Pimcore\Model\Document\Email::getBccAsArray()
Pimcore\Model\Document\Newsletter::getFromAsArray()
Pimcore\Bootstrap::includes()
Pimcore\Http\Request\Resolver\PimcoreContextResolver::CONTEXT_INSTALL
Pimcore\Http\Response\CodeInjector::POSITION_REPLACE
Pimcore\HttpKernel\BundleLocator\BundleLocator::resolveBundlePath()
Pimcore\HttpKernel\BundleLocator\BundleLocatorInterface::resolveBundlePath()
Pimcore\Image\HtmlToImage::getXvfbBinary()
Pimcore\Model\AbstractModel::getResource()
Pimcore\Model\Dao\Mysql\AbstractMysql
Pimcore\Model\Listing\Dao\Mysql\AbstractMysql
Pimcore\Tool\Console::checkExecutingUser()
Pimcore\HttpKernel\Config\SystemConfigParamResource

# LEGACY MODE
Pimcore::isLegacyModeAvailable()
Pimcore\Model\Document\PageSnippet::doRenderWithLegacyStack()
Pimcore\Model\Document\PageSnippet::isLegacy()
Pimcore\Model\Document\PageSnippet::getLegacy()
Pimcore\Model\Document\PageSnippet::setLegacy()
Pimcore\Model\Document::doRenderWithLegacyStack()
Pimcore\ExtensionManager
Pimcore\Helper\LegacyClass
Pimcore\Model\Staticroute::getLegacy()
Pimcore\Model\Staticroute::setLegacy()
Pimcore\Model\Document\Tag\Areablock::isCustomAreaPath()
Pimcore\Model\Document\Tag\Areablock::isBrickEnabled()
Pimcore\Model\Document\Tag\Areablock::getAreaDirectory()
Pimcore\Model\Document\Tag\Areablock::getPathForBrick()
Pimcore\Model\Document\Tag\Areablock::getBrickConfig()
Pimcore\Model\Document\Tag\Areablock::getAreaDirs()
Pimcore\Model\Document\Tag\Areablock::getBrickConfigs()
Pimcore\Model\Document\Tag\Area\Info::setConfig()
Pimcore\Model\Document\Tag\Area\Info::getConfig()
Pimcore\Model\Document\Tag\Area\Info::setPath()
Pimcore\Model\Document\Tag\Area\Info::getPath()
Pimcore\Model\Document\Tag\Area\Info::setName()
Pimcore\Model\Document\Tag\Area\Info::getName()
Pimcore\Model\Document\Tag\Area::getAreaDirs()
Pimcore\Model\Document\Tag\Area::getBrickConfigs()

# Aliases
Pimcore\Glossary\Processor
Pimcore\Admin\Helper\QueryParams
Pimcore\Service\Locale
Pimcore\Localization\Locale
Pimcore\Service\IntlFormatterService
Pimcore\Service\WebPathResolver
Pimcore\Service\RequestMatcherFactory
Pimcore\Service\Context\PimcoreContextGuesser
Pimcore\Service\Request\AbstractRequestResolver
Pimcore\Service\Request\DocumentResolver
Pimcore\Service\Request\EditmodeResolver
Pimcore\Service\Request\PimcoreContextResolver
Pimcore\Service\Request\ResponseHeaderResolver
Pimcore\Service\Request\SiteResolver
Pimcore\Service\Request\TemplateResolver
Pimcore\Service\Request\TemplateVarsResolver
Pimcore\Service\Request\ViewModelResolver

# E-Commerce Framework
Pimcore\Bundle\EcommerceFrameworkBundle\FilterService\FilterType\ProxyFilter
Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Worker\DefaultElasticSearch
Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\DefaultElasticSearch
Pimcore\Bundle\EcommerceFrameworkBundle\Legacy\LegacyClassMappingTool

Method Signature Changes

Pimcore\Templating\Renderer\IncludeRenderer::render() - removed last optional argument $legacyView

E-Commerce Framework

  • Added hierarchy between IProduct and ICheckoutable (and renamed them to ProductInterface and CheckoutableInterface)
    • will be a BC break when class signature looks like class MyClass implements CheckoutableInterface, ProductInterface,
    • no problem, when it is the other way round like class MyClass implements ProductInterface, CheckoutableInterface
  • Renamed all Interfaces to Symfony standard schema - e.g. ICart becomes CartInterface
    • BC layer for all old interfaces in place, issues deprecation warnings in IDE and logs, but it should work without problems
  • Removed Pimcore\Bundle\EcommerceFrameworkBundle\FilterService\FilterType\ProxyFilter
  • Removed Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Worker\DefaultElasticSearch and Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\DefaultElasticSearch
  • Removed Pimcore\Bundle\EcommerceFrameworkBundle\Legacy\LegacyClassMappingTool and pimcore_ecommerce.use_legacy_class_mapping config option.
  • Removed adding environment items CheckoutManager::TRACK_ECOMMERCE and CheckoutManager::TRACK_ECOMMERCE_UNIVERSAL with tracking codes after order commit. Use Tracking Manager instead.
  • Default rounding mode of Decimal changed to PHP_ROUND_HALF_UP.

Consistent API Behavior

We've changed the behavior of many static model getters to return null instead of throwing an exception. Following there's a list of all affected methods.

Pimcore\Model\Glossary::getById()
Pimcore\Model\Notification::getById()
Pimcore\Model\Redirect::getById()
Pimcore\Model\Site::getById()
Pimcore\Model\Site::getByDomain()
Pimcore\Model\Site::getBy()
Pimcore\Model\Version::getById()
Pimcore\Model\WebsiteSetting::getById()
Pimcore\Model\DataObject\ClassDefinition\CustomLayout::getByName()
Pimcore\Model\DataObject\Fieldcollection\Definition::getByKey()
Pimcore\Model\DataObject\Objectbrick\Definition::getByKey()
Pimcore\Model\DataObject\QuantityValue\Unit::getByAbbreviation()
Pimcore\Model\DataObject\QuantityValue\Unit::getByReference()
Pimcore\Model\DataObject\QuantityValue\Unit::getById()
Pimcore\Model\Element\Recyclebin\Item::getById()
Pimcore\Model\Schedule\Task::getById()
Pimcore\Model\Tool\Tracking\Event::getById()
Pimcore\Model\Translation\AbstractTranslation::getByKeyLocalized()