Project

General

Profile

Actions

Bug #103428

closed

Cannot assign string to property TYPO3\CMS\Linkvalidator\Task\ValidatorTask::$depth of type int

Added by Sir Gecco 10 months ago. Updated 3 months ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
scheduler
Target version:
-
Start date:
2024-03-19
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
12
PHP Version:
8.2
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

Upgraded typo3 from v10 to v12. All dependencies and requirements are met.
When calling the scheduler in the backend, it isn't possible due to the following error message:

channel: php
details: Core: Exception handler (WEB): Uncaught TYPO3 Exception: Cannot assign string to property TYPO3\CMS\Linkvalidator\Task\ValidatorTask::$depth of type int | TypeError thrown in file typo3_src-12.4.13/typo3/sysext/scheduler/Classes/Task/TaskSerializer.php in line 39. Requested URL: https://www.mywebsite.com/typo3/module/scheduler?token=--AnonymizedToken--

If the scheduler is called via cli:
Uncaught TYPO3 Exception Cannot assign string to property TYPO3\CMS\Linkvalidator\Task\ValidatorTask::$depth of type int
thrown in file /kunden/443353_6533/websites/_source/typo3_src-12.4.13/typo3/sysext/scheduler/Classes/Task/TaskSerializer.php
in line 39

Re-checked the setup, install-wizard etc. Everything else is running without problems. Can someone confirm this behavior? Tried it with a fresh install on a different host with the same result

Actions #1

Updated by Michael Sollmann 9 months ago

Can confirm this.

Deleting and recreating the linkvalidator task fixes the issue (but does not solve the underlying problem).

Actions #2

Updated by Sir Gecco 9 months ago

Michael Sollmann wrote in #note-1:

Can confirm this.

Deleting and recreating the linkvalidator task fixes the issue (but does not solve the underlying problem).

Thanks for the confirmation and the temp solution. Setting the regarding task as deleted in the table "tx_scheduler_task" fixed the issue.

Actions #3

Updated by Georg Ringer 7 months ago

  • Status changed from New to Closed

with #98453 we move all tasks to commands and get rid of the old syntax.

as I couldn't reproduce the issue I am closing it - hope this is ok for you. feel free to contact me on slack to discuss it if you don't agree

Actions #4

Updated by Andreas Kießling 6 months ago

I have that error as well --> crashes the whole scheduler module with a 503

Actions #5

Updated by Sébastien Delcroix 4 months ago · Edited

I've just had the issue with the last 12.4.19.

I guess the cause is that depth has been serialized as string (for an unknown reason) :

s:8:" * depth";s:3:"999" 

I think we can delete the task and recreate it. For us it was a very old task (created in 2021).

Actions #6

Updated by Klaus Moser 3 months ago

Had the same problem. Here is an updater class that hopefully helps someone:

namespace VENDOR\MySitePackage\Updates;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;

#[UpgradeWizard('mySitePackage_SchedulerTaskUpgradeWizard')]
final class SchedulerTaskUpgradeWizard implements UpgradeWizardInterface
{
    /**
     * Returns the title of the upgrade wizard
     *
     * @return string
     */
    public function getTitle(): string
    {
        return 'mySitePackage_SchedulerTaskUpgradeWizard';
    }

    /**
     * Returns the description of the upgrade wizard
     *
     * @return string
     */
    public function getDescription(): string
    {
        return 'Updates LinkValidator serialized task objects.';
    }

    /**
     * Executes the update
     *
     * @return bool
     */
    public function executeUpdate(): bool
    {
        $rows = $this->getRecords();

        foreach ($rows as $row) {
            $uid = $row['uid'];
            $serializedTaskObject = $row['serialized_task_object'];
            $serializedTaskObject = preg_replace('/depth";s:[\d]+:"(\d+)"/', 'depth";i:$1', $serializedTaskObject);
            $serializedTaskObject = preg_replace('/page";s:[\d]+:"(\d+)"/', 'page";i:$1', $serializedTaskObject);
            $serializedTaskObject = preg_replace('/emailOnBrokenLinkOnly";i:(\d+)/', 'emailOnBrokenLinkOnly";b:$1', $serializedTaskObject);

            $queryBuilder = $this->getQueryBuilder();
            $queryBuilder->update('tx_scheduler_task')
                ->where(
                    $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid))
                )
                ->set('serialized_task_object', $serializedTaskObject)
                ->executeStatement();
        }

        return false;
    }

    /**
     * Checks if the update is necessary
     *
     * @return bool
     */
    public function updateNecessary(): bool
    {
        $rows = $this->getRecords();
        return !empty($rows);
    }

    /**
     * Returns the pre-requisites for the upgrade wizard
     *
     * @return array
     */
    public function getPrerequisites(): array
    {
        return [];
    }

    protected function getRecords(): array
    {
        $queryBuilder = $this->getQueryBuilder();

        return $queryBuilder->select('uid', 'serialized_task_object')
            ->from('tx_scheduler_task')
            ->where(
                $queryBuilder->expr()->or(
                    $queryBuilder->expr()->like(
                        'serialized_task_object',
                        $queryBuilder->createNamedParameter('%depth";s:%')
                    ),
                    $queryBuilder->expr()->like(
                        'serialized_task_object',
                        $queryBuilder->createNamedParameter('%page";s:%')
                    ),
                    $queryBuilder->expr()->like(
                        'serialized_task_object',
                        $queryBuilder->createNamedParameter('%emailOnBrokenLinkOnly";i:%')
                    )
                )
            )
            ->executeQuery()
            ->fetchAllAssociative();
    }

    /**
     * Returns an instance of the QueryBuilder
     *
     * @return QueryBuilder
     */
    protected function getQueryBuilder(): QueryBuilder
    {
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
            ->getQueryBuilderForTable('tx_scheduler_task');

        $queryBuilder->getRestrictions()->removeAll();

        return $queryBuilder;
    }
}
Actions

Also available in: Atom PDF