Deprecation: #97244 - CompositeExpression methods ‘add()’ and ‘addMultiple()’

See Issue #97244

Description

doctrine/dbal deprecated multiple CompositeExpression methods CompositeExpression->add() and CompositeExpression->addMultiple(). Therefore, those methods have also been deprecated in the core facade class (\TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression), to avoid shifting too far away.

Impact

Using CompositeExpression->add() and CompositeExpression->addMultiple() will raise a deprecation level log entry when called.

Affected Installations

In general, instances with extensions that use the deprecated methods CompositeExpression->add() and CompositeExpression->addMultiple(). The extension scanner finds usages of CompositeExpression->addMultiple() with a weak match. The other method is not scanned, as its name is too common.

Migration

The deprecated methods CompositeExpression->add() and CompositeExpression->addMultiple() can be replaced by using the new method CompositeExpression->with().

Note

The replacement method CompositeExpression->with() has already been added in a forward-compatible way in TYPO3 v11. Thus giving extension developers the ability to adopt new methods and still being able to support multiple core versions without workarounds.

For example, the following code:

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;

$compositeExpression = CompositeExpression::or();

$compositeExpression->add(
  $queryBuilder->expr()->eq(
    'field',
    $queryBuilder->createNamedParameter($singleValue)
  )
);
$compositeExpression->addMultiple(
  [
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($value1)
    ),
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($value2)
    ),
    //...
  ]
);

should be replaced with:

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;

$compositeExpression = CompositeExpression::or();

// note, you have to assign the return of with() to the
// variable, otherwise added elements are lost.
$compositeExpression = $compositeExpression->with(
  $queryBuilder->expr()->eq(
    'field',
    $queryBuilder->createNamedParameter($singleValue)
  )
);

// Note the spread operator for the array
$compositeExpression = $compositeExpression->with(
  ...[
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($value1)
    ),
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($value2)
    ),
    //...
  ]
);

The multi expression example can now also be replaced like this:

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;

$compositeExpression = CompositeExpression::or();

// note, you have to assign the return of with() to the
// variable, otherwise added elements are lost.
$compositeExpression = $compositeExpression->with(
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($value1)
    ),
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($value2)
    ),
    //...
);

Extension developers may have used to loop over some data to build multiple expressions which should be connected with and or or, either adding each element with the deprecated add(...) method or collecting it in an array and using deprecated addMultiple(...) method. Both use cases can be replaced with with(...).

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;

$compositeExpression = CompositeExpression::or();

foreach($array as $element) {
  // note, you have to assign the return of with() to the
  // variable, otherwise added elements are lost.
  $compositeExpression = $compositeExpression->with(
    $queryBuilder->expr()->eq(
      'field',
      $queryBuilder->createNamedParameter($element)
    )
  );
}

or

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;

$compositeExpression = CompositeExpression::or();

$expressions = [];
foreach($array as $element) {
  $expressions[] = $queryBuilder->expr()->eq(
    'field',
    $queryBuilder->createNamedParameter($element)
  );
}

// note, you have to assign the return of with() to the
// variable, otherwise added elements are lost.
$compositeExpression = $compositeExpression->with(...$expressions);

Instead of using with() when collecting expressions in an array, it can be used when instantiating the composite expression after the expression collecting:

use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;

$expressions = [];
foreach($array as $element) {
  $expressions[] = $queryBuilder->expr()->eq(
    'field',
    $queryBuilder->createNamedParameter($element)
  );
}

$compositeExpression = CompositeExpression::or(...$expressions);