Fixed Error during upgrade from non-php7.4 compatible XF2 on php7.4

Xon

Well-known member
Affected version
2.1.10 Patch 2
On upgrading an older development instance from 2.1.3 => 2.1.10 patch2, I received these errors;

Code:
> php cmd.php xf-upgrade -v
Current version: 2010370
Upgrade target: 2011072 (2.1.10 Patch 2)
Are you sure you want to continue with the upgrade? [y/n] y

Running upgrade to 2.1.10, step 1... done.
All upgrade steps run up to version 2.1.10 Patch 2.

In Fn.php line 7:

  syntax error, unexpected 'Fn' (T_FN), expecting identifier (T_STRING)

In Fn.php line 7:

  [ParseError]
  syntax error, unexpected 'Fn' (T_FN), expecting identifier (T_STRING)


Exception trace:
  at /var/www/html/src/XF/Template/Compiler/Syntax/Fn.php:7
Composer\Autoload\includeFile() at /var/www/html/src/vendor/composer/ClassLoader.php:322
Composer\Autoload\ClassLoader->loadClass() at n/a:n/a
spl_autoload_call() at n/a:n/a
unserialize() at /var/www/html/src/XF/Mvc/Entity/ValueFormatter.php:17
XF\Mvc\Entity\ValueFormatter->decodeValueFromSource() at /var/www/html/src/XF/Mvc/Entity/ValueFormatter.php:59
XF\Mvc\Entity\ValueFormatter->decodeValueFromSourceExtended() at /var/www/html/src/XF/Mvc/Entity/Manager.php:792
XF\Mvc\Entity\Manager->decodeValueFromSourceExtended() at /var/www/html/src/XF/Mvc/Entity/Entity.php:824
XF\Mvc\Entity\Entity->_columnValueIsDifferent() at /var/www/html/src/XF/Mvc/Entity/Entity.php:632
XF\Mvc\Entity\Entity->set() at /var/www/html/src/XF/Mvc/Entity/Entity.php:548
XF\Mvc\Entity\Entity->__set() at /var/www/html/src/XF/Entity/Template.php:173
XF\Entity\Template->verifyTemplate() at /var/www/html/src/XF/Mvc/Entity/Entity.php:768
XF\Mvc\Entity\Entity->_verifyValueCustom() at /var/www/html/src/XF/Mvc/Entity/Entity.php:613
XF\Mvc\Entity\Entity->set() at /var/www/html/src/XF/Mvc/Entity/Entity.php:548
XF\Mvc\Entity\Entity->__set() at /var/www/html/src/XF/AddOn/DataType/BbCodeMediaSite.php:81
XF\AddOn\DataType\BbCodeMediaSite->importAddOnData() at /var/www/html/src/XF/Job/AddOnData.php:106
XF\Job\AddOnData->run() at /var/www/html/src/XF/Job/Atomic.php:38
XF\Job\Atomic->run() at /var/www/html/src/XF/Job/Manager.php:253
XF\Job\Manager->runJobInternal() at /var/www/html/src/XF/Job/Manager.php:195
XF\Job\Manager->runJobEntry() at /var/www/html/src/XF/Job/Manager.php:146
XF\Job\Manager->runUnique() at /var/www/html/src/XF/Cli/Command/JobRunnerTrait.php:30
XF\Cli\Command\Upgrade->runJob() at /var/www/html/src/XF/Cli/Command/Upgrade.php:202
XF\Cli\Command\Upgrade->execute() at /var/www/html/src/vendor/symfony/console/Command/Command.php:255
Symfony\Component\Console\Command\Command->run() at /var/www/html/src/vendor/symfony/console/Application.php:987
Symfony\Component\Console\Application->doRunCommand() at /var/www/html/src/vendor/symfony/console/Application.php:255
Symfony\Component\Console\Application->doRun() at /var/www/html/src/vendor/symfony/console/Application.php:148
Symfony\Component\Console\Application->run() at /var/www/html/src/XF/Cli/Runner.php:63
XF\Cli\Runner->run() at /var/www/html/cmd.php:16

xf:upgrade [--skip-statistics]

Deleting the entire contents of src/XF, and reuploading gives this error;
Code:
> php cmd.php xf-upgrade -v
Current version: 2011072
Upgrade target: 2011072 (2.1.10 Patch 2)
You are already running the latest version. Rebuild the master data? [y/n] y
PHP Fatal error:  XF\Template\Compiler\Syntax\Expression::compile(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "XF\Template\Compiler\Syntax\Fn" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide an autoloader to load the class definition in /var/www/sites/xf2test.atelieraphelion.com/html/src/XF/Template/Compiler/Syntax/Expression.php on line 22

Fatal error: XF\Template\Compiler\Syntax\Expression::compile(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "XF\Template\Compiler\Syntax\Fn" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide an autoloader to load the class definition in /var/www/sites/xf2test.atelieraphelion.com/html/src/XF/Template/Compiler/Syntax/Expression.php on line 22

Disabling the caching ($config['cache']['enabled'] = false; in config.php) doesn't help.

The template which is erroring is _media_site_embed_youtube with the contents;
HTML:
<div class="bbMediaWrapper">
        <div class="bbMediaWrapper-inner">
                <iframe src="https://www.youtube.com/embed/{$id}?wmode=opaque&start={$start}"
                                width="560" height="315"
                                frameborder="0" allowfullscreen="true"></iframe>
        </div>
</div>

The problem is due to XF\Mvc\Entity\ValueFormatter::decodeValueFromSource;
PHP:
    public function decodeValueFromSource($type, $value)
    {
        if ($value === null)
        {
            return $value;
        }

        switch ($type)
        {
            case Entity::SERIALIZED:
                return @unserialize($value);

            case Entity::SERIALIZED_ARRAY:
                $result = @unserialize($value);
                if (!is_array($result))
                {
                    $result = [];
                }
                return $result;
....
The @ on unserialize doesn't prevent class name errors from throwing an exception. Catching \Throwable however works, if the files exist, doesn't solve restoring an older XF instance onto php 7.4+ and then trying to update. That error can't be caught

Re-uploading the old Fn files, and patching ValueFormatter to return false if \Throwable is thrown from unserialize gives this error;

Code:
> php cmd.php xf:upgrade -v -n
Current version: 2011072
Upgrade target: 2011072 (2.1.10 Patch 2)
You are already running the latest version. Rebuild the master data? [y/n] y

In Compiler.php line 217:

  [ErrorException]
  Argument 1 passed to XF\Template\Compiler::compileAst() must be an instance of XF\Template\Compiler\Ast, false given, called in /var/www/html/src/XF/Service/Template/Compile.php on line 28


Exception trace:
  at /var/www/html/src/XF/Template/Compiler.php:217
XF\Cli\Runner->run() at /var/www/html/cmd.php:16

In Compiler.php line 217:

  [TypeError]
  Argument 1 passed to XF\Template\Compiler::compileAst() must be an instance of XF\Template\Compiler\Ast, false given, called in /var/www/html/src/XF/Service/Template/Compile.php on line 28


Exception trace:
  at /var/www/html/src/XF/Template/Compiler.php:217
XF\Template\Compiler->compileAst() at /var/www/html/src/XF/Service/Template/Compile.php:28
XF\Service\Template\Compile->recompile() at /var/www/html/src/XF/Service/Phrase/Compile.php:71
XF\Service\Phrase\Compile->recompileIncludeContent() at /var/www/html/src/XF/Entity/Phrase.php:198
XF\Entity\Phrase->_postDelete() at /var/www/html/src/XF/Mvc/Entity/Entity.php:1595
XF\Mvc\Entity\Entity->delete() at /var/www/html/src/XF/AddOn/DataType/AbstractDataType.php:117
XF\AddOn\DataType\AbstractDataType->deleteEntity() at /var/www/html/src/XF/AddOn/DataType/AbstractDataType.php:92
XF\AddOn\DataType\AbstractDataType->deleteOrphanedSimple() at /var/www/html/src/XF/AddOn/DataType/Phrase.php:91
XF\AddOn\DataType\Phrase->deleteOrphanedAddOnData() at /var/www/html/src/XF/Job/AddOnData.php:110
XF\Job\AddOnData->run() at /var/www/html/src/XF/Job/Atomic.php:38
XF\Job\Atomic->run() at /var/www/html/src/XF/Job/Manager.php:253
XF\Job\Manager->runJobInternal() at /var/www/html/src/XF/Job/Manager.php:195
XF\Job\Manager->runJobEntry() at /var/www/html/src/XF/Job/Manager.php:146
XF\Job\Manager->runUnique() at /var/www/html/src/XF/Cli/Command/JobRunnerTrait.php:30
XF\Cli\Command\Upgrade->runJob() at /var/www/html/src/XF/Cli/Command/Upgrade.php:202
XF\Cli\Command\Upgrade->execute() at /var/www/html/src/vendor/symfony/console/Command/Command.php:255
Symfony\Component\Console\Command\Command->run() at /var/www/html/src/vendor/symfony/console/Application.php:987
Symfony\Component\Console\Application->doRunCommand() at /var/www/html/src/vendor/symfony/console/Application.php:255
Symfony\Component\Console\Application->doRun() at /var/www/html/src/vendor/symfony/console/Application.php:148
Symfony\Component\Console\Application->run() at /var/www/html/src/XF/Cli/Runner.php:63
XF\Cli\Runner->run() at /var/www/html/cmd.php:16

xf:upgrade [--skip-statistics]

Patching XF\Service\Template\Compile::recompile to check that $template->template_parsed has content and isn't false/null got the master template rebuild working
 
Last edited:
Thank you for reporting this issue, it has now been resolved. We are aiming to include any changes that have been made in a future XF release (2.2.0 Beta 6).

Change log:
Workaround issues when upgrading from older versions of XenForo 2 whilst on PHP 7.4 or greater
There may be a delay before changes are rolled out to the XenForo Community.
 
Just to give some more specifics here, we've restore the old Fn.php file with a class_alias to the new Func version. It looks like we can instantiate an a no-longer-valid class name from an unserialize via this and it should silently work.
 
Just to give some more specifics here, we've restore the old Fn.php file with a class_alias to the new Func version. It looks like we can instantiate an a no-longer-valid class name from an unserialize via this and it should silently work.
You get points for that workaround. I didn't think there'd be an easy fix for this one.
 
Back
Top Bottom