Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions UPGRADE-1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ yokai_batch:

---

### Concrete classes are now `final` and/or `readonly` (BREAKING for subclasses)

As part of the PHP 8.2 modernization, **all concrete classes** in the codebase have been made `final`
and/or `readonly` wherever that was appropriate. Classes that were only marked `@final` in their
docblock now enforce it at the language level.

**Action required:** If you extend any concrete class from this library, refactor your code to use
composition instead. Extending `final` classes or `readonly` classes is a PHP compile error.

---

### New method: `QueryableJobExecutionStorageInterface::purge()` (BREAKING for custom implementations)

A new method has been added to `QueryableJobExecutionStorageInterface`:
Expand Down
16 changes: 6 additions & 10 deletions src/batch-doctrine-dbal/src/DoctrineDBALQueryOffsetReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,28 @@
final readonly class DoctrineDBALQueryOffsetReader implements ItemReaderInterface
{
private Connection $connection;
private string $sql;
private int $batch;

public function __construct(
ConnectionRegistry $doctrine,
string $sql,
private readonly string $sql,
string|null $connection = null,
int $batch = 500,
private readonly int $batch = 500,
) {
if (\mb_strpos($sql, '{limit}') === false || \mb_strpos($sql, '{offset}') === false) {
if (!\str_contains($this->sql, '{limit}') || !\str_contains($this->sql, '{offset}')) {
throw new InvalidArgumentException(
\sprintf('%s $sql argument must contains "{limit}" and "{offset}" for pagination.', __METHOD__),
);
}
if ($batch <= 0) {
if ($this->batch <= 0) {
throw new InvalidArgumentException(
\sprintf('%s $batch argument must be a positive integer.', __METHOD__),
);
}

$connection ??= $doctrine->getDefaultConnectionName();
$connectionName = $connection ?? $doctrine->getDefaultConnectionName();
/** @var Connection $connection */
$connection = $doctrine->getConnection($connection);
$connection = $doctrine->getConnection($connectionName);
$this->connection = $connection;
$this->sql = $sql;
$this->batch = $batch;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Holds the Symfony messenger configuration.
*/
final class MessengerJobsConfiguration
final readonly class MessengerJobsConfiguration
{
public function __construct(
/**
Expand Down
6 changes: 3 additions & 3 deletions src/batch-symfony-validator/src/SkipInvalidItemProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function __construct(
/**
* @var Constraint[]|null
*/
private array|null $contraints = null,
private array|null $constraints = null,
/**
* @var string[]|null
*/
Expand All @@ -31,13 +31,13 @@ public function __construct(

public function process(mixed $item): mixed
{
$violations = $this->validator->validate($item, $this->contraints, $this->groups);
$violations = $this->validator->validate($item, $this->constraints, $this->groups);
if (\count($violations) === 0) {
return $item;
}

throw new SkipItemException($item, new SkipItemOnViolations($violations), [
'constraints' => \iterator_to_array($this->normalizeConstraints($this->contraints)),
'constraints' => \iterator_to_array($this->normalizeConstraints($this->constraints)),
'groups' => $this->groups,
]);
}
Expand Down
3 changes: 1 addition & 2 deletions src/batch/src/Finder/FinderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ interface FinderInterface
*
* @param mixed $subject The subject that should help to find component
*
* @return object The component that matches the subject
* @return T
* @return T The component that matches the subject
*/
public function find(mixed $subject): object;
}
3 changes: 1 addition & 2 deletions src/batch/src/Job/Item/ItemWriterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ interface ItemWriterInterface
/**
* Writes items.
*
* @param iterable $items A batch of items to write
* @param iterable<mixed> $items
* @param iterable<mixed> $items A batch of items to write
*/
public function write(iterable $items): void;
}
4 changes: 1 addition & 3 deletions src/batch/src/Job/JobWithChildJobs.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
/**
* This {@see JobInterface} will execute by triggering child jobs.
* If a child job fails, following child jobs won't be executed.
*
* @final use {@see AbstractDecoratedJob} instead.
*/
class JobWithChildJobs implements JobInterface
final class JobWithChildJobs implements JobInterface
{
public function __construct(
private readonly JobExecutionStorageInterface $executionStorage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function get(JobExecution $execution): mixed
/**
* @return array<string, string>
*/
protected function getVariables(JobExecution $execution): array
private function getVariables(JobExecution $execution): array
{
return [
'{job}' => $execution->getJobName(),
Expand Down
6 changes: 4 additions & 2 deletions src/batch/src/Trigger/Scheduler/CallbackScheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,23 @@ class CallbackScheduler implements SchedulerInterface
/**
* @var list<array{0: callable, 1: string, 2: array<string, mixed>, 3: string|null}>
*/
private array $config = [];
private readonly array $config;

/**
* @param list<array{0: callable, 1: string, 2: array<string, mixed>|null, 3: string|null}> $config
*/
public function __construct(array $config)
{
$normalized = [];
foreach ($config as $entry) {
$this->config[] = [
$normalized[] = [
$entry[0],
$entry[1],
$entry[2] ?? [],
$entry[3] ?? null,
];
}
$this->config = $normalized;
}

/**
Expand Down
1 change: 0 additions & 1 deletion src/batch/src/Trigger/Scheduler/SchedulerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ interface SchedulerInterface
/**
* Get list of job to schedule.
*
* @return ScheduledJob[]
* @return iterable<ScheduledJob>
*/
public function get(JobExecution $execution): iterable;
Expand Down
5 changes: 1 addition & 4 deletions src/batch/src/Trigger/TriggerScheduledJobsJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@
*/
final readonly class TriggerScheduledJobsJob implements JobInterface
{
/**
* @param iterable<SchedulerInterface> $schedulers
*/
public function __construct(
/**
* @phstan-var iterable<SchedulerInterface>
* @var iterable<SchedulerInterface>
*/
private iterable $schedulers,
private JobLauncherInterface $jobLauncher,
Expand Down
Loading