diff --git a/.github/workflows/downgraded_release.yaml b/.github/workflows/downgraded_release.yaml new file mode 100644 index 0000000..0c2cf23 --- /dev/null +++ b/.github/workflows/downgraded_release.yaml @@ -0,0 +1,43 @@ +name: Downgraded Release + +on: + push: + tags: + - '*' + +permissions: + contents: write + +jobs: + downgrade_release: + # Skip if this is already a downgraded tag + if: ${{ !endsWith(github.ref_name, '.74') }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: 8.3 + coverage: none + + - uses: ramsey/composer-install@v3 + + # Downgrade /src to PHP 7.4 + - run: vendor/bin/rector process src --config build/rector-downgrade-php-74.php --ansi + + # Copy PHP 7.4 composer.json + - run: cp build/composer-php-74.json composer.json + + # Remove dev files + - run: rm -rf build .github tests stubs ecs.php phpstan.neon phpunit.xml rector.php .php-cs-fixer.php + + # Tag and push downgraded code + - name: Tag Downgraded Code + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add --all + git commit -m "release PHP 7.4 downgraded version" || echo "No changes to commit" + git tag "${GITHUB_REF#refs/tags/}.74" + git push origin "${GITHUB_REF#refs/tags/}.74" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index f221f07..3abc8b4 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -27,16 +27,8 @@ jobs: strategy: fail-fast: false matrix: - php-version: - - "7.4" - - "8.0" - - "8.1" - - "8.2" - - "8.3" - - "8.4" - dependencies: - - lowest - - highest + php-version: ["8.1", "8.2", "8.3", "8.4"] + dependencies: [lowest, highest] steps: - uses: actions/checkout@v4 @@ -47,19 +39,6 @@ jobs: extensions: mbstring php-version: "${{ matrix.php-version }}" - - if: matrix.php-version == '7.4' - run: > - composer remove --dev --no-update - rector/rector - mll-lab/graphql-php-scalars - spaze/phpstan-disallowed-calls - - - if: matrix.php-version == '8.0' - run: composer remove --dev --no-update rector/rector - - - if: matrix.php-version == '7.4' || matrix.php-version == '8.0' - run: rm -rf src/Enum tests/Enum src/FluidXPlate/Scalars src/Microplate/Scalars tests/FluidXPlate/Scalars tests/Microplate/Scalars - - uses: ramsey/composer-install@v3 with: dependency-versions: "${{ matrix.dependencies }}" @@ -74,16 +53,8 @@ jobs: strategy: fail-fast: false matrix: - php-version: - - "7.4" - - "8.0" - - "8.1" - - "8.2" - - "8.3" - - "8.4" - dependencies: - - lowest - - highest + php-version: ["8.1", "8.2", "8.3", "8.4"] + dependencies: [lowest, highest] steps: - uses: actions/checkout@v4 @@ -94,19 +65,6 @@ jobs: extensions: mbstring php-version: "${{ matrix.php-version }}" - - if: matrix.php-version == '7.4' - run: > - composer remove --dev --no-update - rector/rector - mll-lab/graphql-php-scalars - spaze/phpstan-disallowed-calls - - - if: matrix.php-version == '8.0' - run: composer remove --dev --no-update rector/rector - - - if: matrix.php-version == '7.4' || matrix.php-version == '8.0' - run: rm -rf src/Enum tests/Enum src/FluidXPlate/Scalars src/Microplate/Scalars tests/FluidXPlate/Scalars tests/Microplate/Scalars - - uses: ramsey/composer-install@v3 with: dependency-versions: "${{ matrix.dependencies }}" @@ -131,3 +89,56 @@ jobs: # Not using v4 due to the breaking changes described in https://github.com/codecov/codecov-action/releases/tag/v4.0.0 - uses: codecov/codecov-action@v3 + + downgraded-build-validate: + name: "Downgraded Build Validate (PHP 7.4, ${{ matrix.dependencies }})" + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + dependencies: [lowest, highest] + + steps: + - uses: actions/checkout@v4 + + - name: "Setup PHP 8.3 (Rector)" + uses: shivammathur/setup-php@v2 + with: + php-version: 8.3 + coverage: none + + - uses: ramsey/composer-install@v3 + + - name: "Downgrade src and tests" + run: | + vendor/bin/rector process src tests --config build/rector-downgrade-php-74.php --ansi + + - name: "Prepare downgraded composer.json" + run: | + cp build/composer-php-74.json composer.json + rm -f composer.lock + + - name: "Remove tests incompatible with PHP 7.4" + run: | + rm -rf tests/PHPStan # Requires PHPStan testing framework + rm -rf tests/Enum # PHP 8.1+ enums cannot be downgraded + rm -rf tests/FluidXPlate # Requires graphql-php-scalars (optional) + rm -rf tests/Qiaxcel # Requires phpspreadsheet (optional) + rm -rf tests/LightcyclerExportSheet # Uses Collection::firstOrFail (Laravel 9+) + + - name: "Setup PHP 7.4" + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + coverage: none + + - name: "Install downgraded dependencies" + run: | + composer update --no-interaction --prefer-dist ${{ matrix.dependencies == 'lowest' && '--prefer-lowest --prefer-stable' || '' }} + + - name: "Validate downgraded composer.json" + run: composer validate --no-check-publish + + - name: "Run PHPUnit on downgraded src" + run: vendor/bin/phpunit diff --git a/CHANGELOG.md b/CHANGELOG.md index 502082a..211e886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## v6.0.0 + +### Changed + +- Require PHP ^8.1 for the main package +- Use PHP 8.1 features: `readonly` properties, union type syntax + +### Added + +- Automatic PHP 7.4 downgraded releases via `.74` tag suffix (e.g., `v6.0.0.74`) +- GitHub Actions workflow for automated downgrade releases + +### Migration + +Users on PHP 7.4 or 8.0 should use the `.74` tagged releases: +```sh +composer require mll-lab/php-utils:v6.0.0.74 +``` + # [5.23.0](https://github.com/mll-lab/php-utils/compare/v5.22.0...v5.23.0) (2025-12-08) diff --git a/README.md b/README.md index 3cc88c1..d756a4b 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,16 @@ Install through composer composer require mll-lab/php-utils ``` +### PHP 7.4 / 8.0 Support + +The main package requires PHP ^8.1. For PHP 7.4 or 8.0, use the automatically generated `.74` releases: + +```sh +composer require mll-lab/php-utils:v6.0.0.74 +``` + +These releases are automatically downgraded using [Rector](https://getrector.org) and published alongside each main release. + ## Usage See [tests](tests). diff --git a/build/composer-php-74.json b/build/composer-php-74.json new file mode 100644 index 0000000..30d01a4 --- /dev/null +++ b/build/composer-php-74.json @@ -0,0 +1,63 @@ +{ + "name": "mll-lab/php-utils", + "description": "Shared PHP utility functions of MLL", + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Benedikt Franke", + "email": "benedikt@franke.tech" + } + ], + "homepage": "https://github.com/mll-lab/php-utils", + "support": { + "issues": "https://github.com/mll-lab/php-utils/issues", + "source": "https://github.com/mll-lab/php-utils" + }, + "require": { + "php": "^7.4 || ^8.0", + "ext-calendar": "*", + "ext-simplexml": "*", + "illuminate/support": "^8.77 || ^9 || ^10", + "mll-lab/str_putcsv": "^1", + "nesbot/carbon": "^2.62.1", + "ramsey/uuid": "^3 || ^4", + "thecodingmachine/safe": "^1 || ^2" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "suggest": { + "mll-lab/graphql-php-scalars": "To use the provided scalar types for GraphQL servers, requires version ^6.3", + "phpoffice/phpspreadsheet": "Required if using QiaxcelImport", + "spaze/phpstan-disallowed-calls": "Required when using the PHPStan configuration from rules.neon directly or through the extension installer" + }, + "autoload": { + "psr-4": { + "MLL\\Utils\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "MLL\\Utils\\Tests\\": "tests/" + } + }, + "config": { + "audit": { + "ignore": [ + "PKSA-8qx3-n5y5-vvnd" + ], + "abandoned": "ignore" + }, + "block-insecure": false, + "sort-packages": true + }, + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + } +} diff --git a/build/rector-downgrade-php-74.php b/build/rector-downgrade-php-74.php new file mode 100644 index 0000000..ba8312c --- /dev/null +++ b/build/rector-downgrade-php-74.php @@ -0,0 +1,14 @@ +withDowngradeSets(php74: true) + ->withConfiguredRule(DowngradeAttributeToAnnotationRector::class, [ + new DowngradeAttributeToAnnotation( + 'PHPUnit\Framework\Attributes\DataProvider', + 'dataProvider' + ), + ]); diff --git a/composer.json b/composer.json index 9f3cb7c..362bfbc 100644 --- a/composer.json +++ b/composer.json @@ -15,10 +15,10 @@ "source": "https://github.com/mll-lab/php-utils" }, "require": { - "php": "^7.4 || ^8", + "php": "^8.1", "ext-calendar": "*", "ext-simplexml": "*", - "illuminate/support": "^8.73 || ^9 || ^10 || ^11 || ^12", + "illuminate/support": "^8.77 || ^9 || ^10 || ^11 || ^12", "mll-lab/str_putcsv": "^1", "nesbot/carbon": "^2.62.1 || ^3", "ramsey/uuid": "^3 || ^4", diff --git a/rector.php b/rector.php index 88c0015..d068315 100644 --- a/rector.php +++ b/rector.php @@ -9,6 +9,8 @@ SetList::CODE_QUALITY, SetList::TYPE_DECLARATION, SetList::RECTOR_PRESET, + SetList::PHP_80, + SetList::PHP_81, PHPUnitSetList::PHPUNIT_40, PHPUnitSetList::PHPUNIT_50, PHPUnitSetList::PHPUNIT_60, @@ -19,7 +21,6 @@ PHPUnitSetList::PHPUNIT_110, PHPUnitSetList::PHPUNIT_CODE_QUALITY, ]) - ->withPhpSets() ->withRules([ Rector\PHPUnit\CodeQuality\Rector\Class_\PreferPHPUnitSelfCallRector::class, ]) @@ -28,6 +29,9 @@ Rector\CodeQuality\Rector\Concat\JoinStringConcatRector::class => [ __DIR__ . '/tests/CSVArrayTest.php', // keep `\r\n` for readability ], + Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class => [ + __DIR__ . '/src/IlluminaSampleSheet/V2/BclConvert/BclSample.php', // currently relies on `get_object_vars()` and breaks behaviour. + ], ]) ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) ->withBootstrapFiles([ diff --git a/src/DnaSequence.php b/src/DnaSequence.php index ee71da4..03cc976 100644 --- a/src/DnaSequence.php +++ b/src/DnaSequence.php @@ -19,7 +19,7 @@ public function reverse(): string $parts = mb_str_split($this->sequence); // @phpstan-ignore-line theCodingMachineSafe.function (safe from PHP 8.0) $reversedParts = array_reverse($parts); - return implode($reversedParts); + return implode('', $reversedParts); } public function complement(): string diff --git a/src/FluidXPlate/FluidXPlate.php b/src/FluidXPlate/FluidXPlate.php index 195e007..c484c6d 100644 --- a/src/FluidXPlate/FluidXPlate.php +++ b/src/FluidXPlate/FluidXPlate.php @@ -16,7 +16,7 @@ class FluidXPlate public string $rackID; /** @var Microplate */ - private Microplate $microplate; + private readonly Microplate $microplate; public function __construct(string $rackID) { @@ -51,7 +51,7 @@ public function addToNextFreeWell(string $content, FlowDirection $flowDirection) /** @return Collection */ public function wells(): Collection { - return $this->microplate->wells(); + return $this->microplate->wells(); // @phpstan-ignore return.type (generic not inferred) } /** @return Collection */ @@ -63,6 +63,6 @@ public function freeWells(): Collection /** @return Collection */ public function filledWells(): Collection { - return $this->microplate->filledWells(); + return $this->microplate->filledWells(); // @phpstan-ignore return.type (generic not inferred) } } diff --git a/src/IlluminaSampleSheet/V1/DualIndex.php b/src/IlluminaSampleSheet/V1/DualIndex.php index 0b993eb..f88df26 100644 --- a/src/IlluminaSampleSheet/V1/DualIndex.php +++ b/src/IlluminaSampleSheet/V1/DualIndex.php @@ -4,21 +4,12 @@ class DualIndex extends Index { - public string $i7IndexID; - - public string $index; - - public string $i5IndexID; - - public string $index2; - - public function __construct(string $i7IndexID, string $index, string $i5IndexID, string $index2) - { - $this->i7IndexID = $i7IndexID; - $this->index = $index; - $this->i5IndexID = $i5IndexID; - $this->index2 = $index2; - + public function __construct( + public string $i7IndexID, + public string $index, + public string $i5IndexID, + public string $index2 + ) { $this->validate(); } diff --git a/src/IlluminaSampleSheet/V1/HeaderSection.php b/src/IlluminaSampleSheet/V1/HeaderSection.php index 208d820..b5c8994 100644 --- a/src/IlluminaSampleSheet/V1/HeaderSection.php +++ b/src/IlluminaSampleSheet/V1/HeaderSection.php @@ -6,45 +6,17 @@ class HeaderSection implements Section { - public ?string $iemFileVersion; - - public ?string $experimentName; - - public ?string $investigatorName; - - public string $date; - - public string $workflow; - - public string $application; - - public string $assay; - - public string $description; - - public string $chemistry; - public function __construct( - string $iemFileVersion, - string $investigatorName, - string $experimentName, - string $date, - string $workflow, - string $application, - string $assay, - string $description, - string $chemistry - ) { - $this->chemistry = $chemistry; - $this->description = $description; - $this->assay = $assay; - $this->application = $application; - $this->workflow = $workflow; - $this->date = $date; - $this->investigatorName = $investigatorName; - $this->experimentName = $experimentName; - $this->iemFileVersion = $iemFileVersion; - } + public ?string $iemFileVersion, + public ?string $investigatorName, + public ?string $experimentName, + public string $date, + public string $workflow, + public string $application, + public string $assay, + public string $description, + public string $chemistry + ) {} public function convertSectionToString(): string { diff --git a/src/IlluminaSampleSheet/V1/ReadsSection.php b/src/IlluminaSampleSheet/V1/ReadsSection.php index fcde207..f0fea7d 100644 --- a/src/IlluminaSampleSheet/V1/ReadsSection.php +++ b/src/IlluminaSampleSheet/V1/ReadsSection.php @@ -6,15 +6,10 @@ class ReadsSection implements Section { - private int $read1Cycles; - - private int $read2Cycles; - - public function __construct(int $read1Cycles, int $read2Cycles) - { - $this->read1Cycles = $read1Cycles; - $this->read2Cycles = $read2Cycles; - } + public function __construct( + private readonly int $read1Cycles, + private readonly int $read2Cycles + ) {} public function convertSectionToString(): string { diff --git a/src/IlluminaSampleSheet/V1/RowForDualIndexWithLane.php b/src/IlluminaSampleSheet/V1/RowForDualIndexWithLane.php index de197ce..29ea0d3 100644 --- a/src/IlluminaSampleSheet/V1/RowForDualIndexWithLane.php +++ b/src/IlluminaSampleSheet/V1/RowForDualIndexWithLane.php @@ -4,30 +4,17 @@ class RowForDualIndexWithLane extends Row { - public DualIndex $dualIndex; - - public int $lane; - - public string $sampleName; - - public string $samplePlate; - - public string $sampleWell; - - public string $sampleProject; - - public string $description; - - public function __construct(DualIndex $dualIndex, int $lane, string $sampleID, string $sampleName, string $samplePlate, string $sampleWell, string $sampleProject, string $description) - { - $this->dualIndex = $dualIndex; - $this->lane = $lane; + public function __construct( + public DualIndex $dualIndex, + public int $lane, + string $sampleID, + public string $sampleName, + public string $samplePlate, + public string $sampleWell, + public string $sampleProject, + public string $description + ) { $this->sampleID = $sampleID; - $this->sampleName = $sampleName; - $this->samplePlate = $samplePlate; - $this->sampleWell = $sampleWell; - $this->sampleProject = $sampleProject; - $this->description = $description; } public function toString(): string diff --git a/src/IlluminaSampleSheet/V1/RowForDualIndexWithoutLane.php b/src/IlluminaSampleSheet/V1/RowForDualIndexWithoutLane.php index 2d0c6dc..4a24a63 100644 --- a/src/IlluminaSampleSheet/V1/RowForDualIndexWithoutLane.php +++ b/src/IlluminaSampleSheet/V1/RowForDualIndexWithoutLane.php @@ -4,27 +4,16 @@ class RowForDualIndexWithoutLane extends Row { - public DualIndex $dualIndex; - - public string $sampleName; - - public string $samplePlate; - - public string $sampleWell; - - public string $sampleProject; - - public string $description; - - public function __construct(DualIndex $dualIndex, string $sampleID, string $sampleName, string $samplePlate, string $sampleWell, string $sampleProject, string $description) - { - $this->dualIndex = $dualIndex; + public function __construct( + public DualIndex $dualIndex, + string $sampleID, + public string $sampleName, + public string $samplePlate, + public string $sampleWell, + public string $sampleProject, + public string $description + ) { $this->sampleID = $sampleID; - $this->sampleName = $sampleName; - $this->samplePlate = $samplePlate; - $this->sampleWell = $sampleWell; - $this->sampleProject = $sampleProject; - $this->description = $description; } public function toString(): string diff --git a/src/IlluminaSampleSheet/V1/SettingsSection.php b/src/IlluminaSampleSheet/V1/SettingsSection.php index 6fc8b61..0744373 100644 --- a/src/IlluminaSampleSheet/V1/SettingsSection.php +++ b/src/IlluminaSampleSheet/V1/SettingsSection.php @@ -6,15 +6,10 @@ class SettingsSection implements Section { - private ?string $adapter; - - private ?string $adapterRead2; - - public function __construct(?string $adapter = null, ?string $adapterRead2 = null) - { - $this->adapter = $adapter; - $this->adapterRead2 = $adapterRead2; - } + public function __construct( + private readonly ?string $adapter = null, + private readonly ?string $adapterRead2 = null + ) {} public function convertSectionToString(): string { diff --git a/src/IlluminaSampleSheet/V2/BclConvert/BclConvertSection.php b/src/IlluminaSampleSheet/V2/BclConvert/BclConvertSection.php index e98757a..70caaa4 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/BclConvertSection.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/BclConvertSection.php @@ -7,15 +7,10 @@ class BclConvertSection implements Section { - protected SettingsSection $settingsSection; - - protected DataSection $dataSection; - - public function __construct(SettingsSection $settingsSection, DataSection $dataSection) - { - $this->settingsSection = $settingsSection; - $this->dataSection = $dataSection; - } + public function __construct( + protected SettingsSection $settingsSection, + protected DataSection $dataSection + ) {} public function convertSectionToString(): string { diff --git a/src/IlluminaSampleSheet/V2/BclConvert/CycleType.php b/src/IlluminaSampleSheet/V2/BclConvert/CycleType.php index f26983d..614b196 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/CycleType.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/CycleType.php @@ -9,12 +9,9 @@ class CycleType public const UMI_CYCLE = 'U'; public const INDEX_CYCLE = 'I'; - public string $value; - - public function __construct(string $value) - { - $this->value = $value; - } + public function __construct( + public string $value + ) {} public static function READ_CYCLE(): self { diff --git a/src/IlluminaSampleSheet/V2/BclConvert/CycleTypeWithCount.php b/src/IlluminaSampleSheet/V2/BclConvert/CycleTypeWithCount.php index 039da11..2681721 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/CycleTypeWithCount.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/CycleTypeWithCount.php @@ -4,15 +4,10 @@ class CycleTypeWithCount { - protected CycleType $cycleType; - - public int $count; - - public function __construct(CycleType $cycleType, int $count) - { - $this->cycleType = $cycleType; - $this->count = $count; - } + public function __construct( + protected CycleType $cycleType, + public int $count + ) {} public function toString(): string { diff --git a/src/IlluminaSampleSheet/V2/BclConvert/DataSection.php b/src/IlluminaSampleSheet/V2/BclConvert/DataSection.php index db3fc4f..a67d0f1 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/DataSection.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/DataSection.php @@ -59,7 +59,7 @@ protected function generateDataHeaderByProperties(array $samplePropertiesOfFirst $samplePropertiesOfFirstSample = array_filter($samplePropertiesOfFirstSample, fn (string $value): bool // @phpstan-ignore-next-line Variable property access on a non-object required here => $this->dataRows[0]->$value !== null); - $samplePropertiesOfFirstSample = array_map(fn (string $value): string => ucfirst($value), $samplePropertiesOfFirstSample); + $samplePropertiesOfFirstSample = array_map(ucfirst(...), $samplePropertiesOfFirstSample); return implode(',', $samplePropertiesOfFirstSample); } diff --git a/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycle.php b/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycle.php index 54c035b..819998a 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycle.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycle.php @@ -6,14 +6,10 @@ class OverrideCycle { - /** @var array */ - public array $cycles; - /** @param array $cycles */ - public function __construct(array $cycles) - { - $this->cycles = $cycles; - } + public function __construct( + public array $cycles + ) {} /** @param bool|null $isSecondIndexAndForwardDirection null if it is not the secondIndex, true if it is the secondIndex and forwardDirection, false if it is the secondIndex and reverseDirection */ public function toString(int $fillUpToMax, ?bool $isSecondIndexAndForwardDirection): string diff --git a/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycles.php b/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycles.php index 03715cf..617f482 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycles.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/OverrideCycles.php @@ -15,15 +15,17 @@ class OverrideCycles public ?OverrideCycle $read2; - private DataSection $dataSection; - - public function __construct(DataSection $dataSection, string $read1, string $index1, ?string $index2, ?string $read2) - { + public function __construct( + private readonly DataSection $dataSection, + string $read1, + string $index1, + ?string $index2, + ?string $read2 + ) { $this->read1 = $this->makeOverrideCycle($read1); $this->index1 = $this->makeOverrideCycle($index1); $this->index2 = $index2 !== null ? $this->makeOverrideCycle($index2) : null; $this->read2 = $read2 !== null ? $this->makeOverrideCycle($read2) : null; - $this->dataSection = $dataSection; } public function toString(): string diff --git a/src/IlluminaSampleSheet/V2/BclConvert/SettingsSection.php b/src/IlluminaSampleSheet/V2/BclConvert/SettingsSection.php index 7279c24..b248c2f 100644 --- a/src/IlluminaSampleSheet/V2/BclConvert/SettingsSection.php +++ b/src/IlluminaSampleSheet/V2/BclConvert/SettingsSection.php @@ -7,19 +7,12 @@ class SettingsSection implements Section { - public string $softwareVersion; - - public FastQCompressionFormat $fastqCompressionFormat; - public ?bool $trimUMI = null; public function __construct( - string $softwareVersion, - FastQCompressionFormat $fastqCompressionFormat - ) { - $this->softwareVersion = $softwareVersion; - $this->fastqCompressionFormat = $fastqCompressionFormat; - } + public string $softwareVersion, + public FastQCompressionFormat $fastqCompressionFormat + ) {} public function convertSectionToString(): string { diff --git a/src/IlluminaSampleSheet/V2/Enums/FastQCompressionFormat.php b/src/IlluminaSampleSheet/V2/Enums/FastQCompressionFormat.php index d813820..aed0df4 100644 --- a/src/IlluminaSampleSheet/V2/Enums/FastQCompressionFormat.php +++ b/src/IlluminaSampleSheet/V2/Enums/FastQCompressionFormat.php @@ -7,12 +7,9 @@ class FastQCompressionFormat public const GZIP = 'gzip'; public const DRAGEN = 'dragen'; - public string $value; - - public function __construct(string $value) - { - $this->value = $value; - } + public function __construct( + public string $value + ) {} public static function GZIP(): self { diff --git a/src/IlluminaSampleSheet/V2/HeaderSection.php b/src/IlluminaSampleSheet/V2/HeaderSection.php index 8731f43..3159036 100644 --- a/src/IlluminaSampleSheet/V2/HeaderSection.php +++ b/src/IlluminaSampleSheet/V2/HeaderSection.php @@ -11,8 +11,6 @@ class HeaderSection implements Section protected string $fileFormatVersion = self::FILE_FORMAT_VERSION; - public string $runName; - public ?string $runDescription = null; public ?string $instrumentType = null; @@ -22,10 +20,9 @@ class HeaderSection implements Section /** @var array */ protected array $customParams = []; - public function __construct(string $runName) - { - $this->runName = $runName; - } + public function __construct( + public string $runName + ) {} public static function isForwardIndexOrientation(): bool { diff --git a/src/LightcyclerExportSheet/LightcyclerSample.php b/src/LightcyclerExportSheet/LightcyclerSample.php index 2e5e3f0..52a6437 100644 --- a/src/LightcyclerExportSheet/LightcyclerSample.php +++ b/src/LightcyclerExportSheet/LightcyclerSample.php @@ -7,29 +7,12 @@ class LightcyclerSample { - public string $name; - - /** @var Coordinates */ - public Coordinates $coordinates; - - public float $calculatedConcentration; - - public float $crossingPoint; - - public ?float $standardConcentration; - /** @param Coordinates $coordinates */ public function __construct( - string $name, - Coordinates $coordinates, - float $calculatedConcentration, - float $crossingPoint, - ?float $standardConcentration = null - ) { - $this->standardConcentration = $standardConcentration; - $this->crossingPoint = $crossingPoint; - $this->calculatedConcentration = $calculatedConcentration; - $this->coordinates = $coordinates; - $this->name = $name; - } + public string $name, + public Coordinates $coordinates, + public float $calculatedConcentration, + public float $crossingPoint, + public ?float $standardConcentration = null + ) {} } diff --git a/src/LightcyclerSampleSheet/AbsoluteQuantificationSample.php b/src/LightcyclerSampleSheet/AbsoluteQuantificationSample.php index 9a236b8..08b7e88 100644 --- a/src/LightcyclerSampleSheet/AbsoluteQuantificationSample.php +++ b/src/LightcyclerSampleSheet/AbsoluteQuantificationSample.php @@ -7,34 +7,15 @@ class AbsoluteQuantificationSample { - public string $sampleName; - - public string $filterCombination; - - public string $hexColor; - - public string $sampleType; - - /** Key used to determine replication grouping - samples with the same key will replicate to the first occurrence */ - public string $replicationOfKey; - - public ?int $concentration; - public function __construct( - string $sampleName, - string $filterCombination, - string $hexColor, - string $sampleType, - string $replicationOfKey, - ?int $concentration - ) { - $this->sampleName = $sampleName; - $this->filterCombination = $filterCombination; - $this->hexColor = $hexColor; - $this->sampleType = $sampleType; - $this->replicationOfKey = $replicationOfKey; - $this->concentration = $concentration; - } + public string $sampleName, + public string $filterCombination, + public string $hexColor, + public string $sampleType, + /** Key used to determine replication grouping - samples with the same key will replicate to the first occurrence */ + public string $replicationOfKey, + public ?int $concentration + ) {} public static function formatConcentration(?int $concentration): ?string { diff --git a/src/LightcyclerSampleSheet/RelativeQuantificationSample.php b/src/LightcyclerSampleSheet/RelativeQuantificationSample.php index d686997..0038f78 100644 --- a/src/LightcyclerSampleSheet/RelativeQuantificationSample.php +++ b/src/LightcyclerSampleSheet/RelativeQuantificationSample.php @@ -7,27 +7,13 @@ class RelativeQuantificationSample { - public string $sampleName; - - public string $filterCombination; - - public string $hexColor; - - /** @var Coordinates|null */ - public ?Coordinates $replicationOf; - /** @param Coordinates|null $replicationOf */ public function __construct( - string $sampleName, - string $filterCombination, - string $hexColor, - ?Coordinates $replicationOf - ) { - $this->sampleName = $sampleName; - $this->filterCombination = $filterCombination; - $this->hexColor = $hexColor; - $this->replicationOf = $replicationOf; - } + public string $sampleName, + public string $filterCombination, + public string $hexColor, + public ?Coordinates $replicationOf + ) {} /** @return list */ public function toSerializableArray(string $coordinatesString): array diff --git a/src/Microplate/AbstractMicroplate.php b/src/Microplate/AbstractMicroplate.php index c8f5178..7cb7f02 100644 --- a/src/Microplate/AbstractMicroplate.php +++ b/src/Microplate/AbstractMicroplate.php @@ -16,14 +16,10 @@ abstract class AbstractMicroplate { public const EMPTY_WELL = null; - /** @var TCoordinateSystem */ - public CoordinateSystem $coordinateSystem; - /** @param TCoordinateSystem $coordinateSystem */ - public function __construct(CoordinateSystem $coordinateSystem) - { - $this->coordinateSystem = $coordinateSystem; - } + public function __construct( + public CoordinateSystem $coordinateSystem + ) {} /** @return WellsCollection */ abstract public function wells(): Collection; diff --git a/src/Microplate/AbstractSection.php b/src/Microplate/AbstractSection.php index 8b66b8f..8592851 100644 --- a/src/Microplate/AbstractSection.php +++ b/src/Microplate/AbstractSection.php @@ -7,16 +7,13 @@ /** @template TSectionWell */ abstract class AbstractSection { - /** @var SectionedMicroplate */ - public SectionedMicroplate $sectionedMicroplate; - /** @var Collection */ public Collection $sectionItems; /** @param SectionedMicroplate $sectionedMicroplate */ - public function __construct(SectionedMicroplate $sectionedMicroplate) - { - $this->sectionedMicroplate = $sectionedMicroplate; + public function __construct( + public SectionedMicroplate $sectionedMicroplate + ) { $this->sectionItems = new Collection(); } diff --git a/src/Microplate/Coordinates.php b/src/Microplate/Coordinates.php index a13c7b4..0fdb73b 100644 --- a/src/Microplate/Coordinates.php +++ b/src/Microplate/Coordinates.php @@ -84,7 +84,7 @@ public static function fromString(string $coordinatesString, CoordinateSystem $c if ($valid === 0) { $firstValidExample = Arr::first($rows) . Arr::first($columns); $lastValidExample = Arr::last($rows) . Arr::last($columns); - $coordinateSystemClass = get_class($coordinateSystem); + $coordinateSystemClass = $coordinateSystem::class; throw new \InvalidArgumentException("Expected coordinates between {$firstValidExample} and {$lastValidExample} for {$coordinateSystemClass}, got: {$coordinatesString}."); } /** @var array{1: string, 2: string} $matches */ @@ -103,25 +103,19 @@ public static function fromPosition(int $position, FlowDirection $direction, Coo { self::assertPositionInRange($coordinateSystem, $position); - switch ($direction->value) { - case FlowDirection::COLUMN: - return new static( - $coordinateSystem->rowForColumnFlowPosition($position), - $coordinateSystem->columnForColumnFlowPosition($position), - $coordinateSystem - ); - - case FlowDirection::ROW: - return new static( - $coordinateSystem->rowForRowFlowPosition($position), - $coordinateSystem->columnForRowFlowPosition($position), - $coordinateSystem - ); - // @codeCoverageIgnoreStart all Enums are listed and this should never happen - default: - throw new UnexpectedFlowDirection($direction); - // @codeCoverageIgnoreEnd - } + return match ($direction->value) { + FlowDirection::COLUMN => new static( + $coordinateSystem->rowForColumnFlowPosition($position), + $coordinateSystem->columnForColumnFlowPosition($position), + $coordinateSystem + ), + FlowDirection::ROW => new static( + $coordinateSystem->rowForRowFlowPosition($position), + $coordinateSystem->columnForRowFlowPosition($position), + $coordinateSystem + ), + default => throw new UnexpectedFlowDirection($direction), + }; } public function toString(): string @@ -143,16 +137,11 @@ public function position(FlowDirection $direction): int /** @var int<0, max> $columnIndex Must be found, since __construct enforces $this->column is valid */ $columnIndex = array_search($this->column, $this->coordinateSystem->columns(), true); - switch ($direction->value) { - case FlowDirection::ROW: - return $rowIndex * count($this->coordinateSystem->columns()) + $columnIndex + 1; - case FlowDirection::COLUMN: - return $columnIndex * count($this->coordinateSystem->rows()) + $rowIndex + 1; - // @codeCoverageIgnoreStart all Enums are listed and this should never happen - default: - throw new UnexpectedFlowDirection($direction); - // @codeCoverageIgnoreEnd - } + return match ($direction->value) { + FlowDirection::ROW => $rowIndex * count($this->coordinateSystem->columns()) + $columnIndex + 1, + FlowDirection::COLUMN => $columnIndex * count($this->coordinateSystem->rows()) + $rowIndex + 1, + default => throw new UnexpectedFlowDirection($direction), + }; } /** diff --git a/src/Microplate/Enums/FlowDirection.php b/src/Microplate/Enums/FlowDirection.php index 73d3081..3bf6aa7 100644 --- a/src/Microplate/Enums/FlowDirection.php +++ b/src/Microplate/Enums/FlowDirection.php @@ -7,12 +7,9 @@ class FlowDirection public const ROW = 'ROW'; public const COLUMN = 'COLUMN'; - public string $value; - - public function __construct(string $value) - { - $this->value = $value; - } + public function __construct( + public string $value + ) {} public static function ROW(): self { diff --git a/src/Microplate/FullColumnSection.php b/src/Microplate/FullColumnSection.php index 6a87c26..759dfa6 100644 --- a/src/Microplate/FullColumnSection.php +++ b/src/Microplate/FullColumnSection.php @@ -66,8 +66,7 @@ private function growSection(): void } } - /** @return false|int */ - private function nextReservedWell() + private function nextReservedWell(): int|false { $search = $this->sectionItems->search(AbstractMicroplate::EMPTY_WELL); assert($search === false || is_int($search)); // @phpstan-ignore-line function.alreadyNarrowedType (not yet supported by PHPStan of older versions) diff --git a/src/Microplate/MicroplateSet/Location.php b/src/Microplate/MicroplateSet/Location.php index ff28f51..58e4055 100644 --- a/src/Microplate/MicroplateSet/Location.php +++ b/src/Microplate/MicroplateSet/Location.php @@ -8,15 +8,9 @@ /** @template TCoordinateSystem of CoordinateSystem */ class Location { - public string $plateID; - - /** @var \MLL\Utils\Microplate\Coordinates */ - public Coordinates $coordinates; - /** @param \MLL\Utils\Microplate\Coordinates $coordinates */ - public function __construct(Coordinates $coordinates, string $plateID) - { - $this->coordinates = $coordinates; - $this->plateID = $plateID; - } + public function __construct( + public Coordinates $coordinates, + public string $plateID + ) {} } diff --git a/src/Microplate/MicroplateSet/MicroplateSet.php b/src/Microplate/MicroplateSet/MicroplateSet.php index f00b249..608472d 100644 --- a/src/Microplate/MicroplateSet/MicroplateSet.php +++ b/src/Microplate/MicroplateSet/MicroplateSet.php @@ -9,14 +9,10 @@ /** @template TCoordinateSystem of CoordinateSystem */ abstract class MicroplateSet { - /** @var TCoordinateSystem */ - public CoordinateSystem $coordinateSystem; - /** @param TCoordinateSystem $coordinateSystem */ - public function __construct(CoordinateSystem $coordinateSystem) - { - $this->coordinateSystem = $coordinateSystem; - } + public function __construct( + public CoordinateSystem $coordinateSystem + ) {} /** @return list */ abstract public function plateIDs(): array; diff --git a/src/Microplate/WellWithCoordinates.php b/src/Microplate/WellWithCoordinates.php index ba79d0f..525ca04 100644 --- a/src/Microplate/WellWithCoordinates.php +++ b/src/Microplate/WellWithCoordinates.php @@ -8,19 +8,12 @@ */ class WellWithCoordinates { - /** @var TWell */ - public $content; - - /** @var Coordinates */ - public Coordinates $coordinates; - /** * @param TWell $content * @param Coordinates $coordinates */ - public function __construct($content, Coordinates $coordinates) - { - $this->content = $content; - $this->coordinates = $coordinates; - } + public function __construct( + public $content, + public Coordinates $coordinates + ) {} } diff --git a/src/Number.php b/src/Number.php index 55a74f0..effa6b0 100644 --- a/src/Number.php +++ b/src/Number.php @@ -13,10 +13,8 @@ class Number * @param float|int $min * @param float|int $max * @param float|int $current - * - * @return float|int */ - public static function clamp($min, $max, $current) + public static function clamp($min, $max, $current): float|int { return max($min, min($max, $current)); } diff --git a/src/PHPStan/Rules/NoAssignmentInIfRule.php b/src/PHPStan/Rules/NoAssignmentInIfRule.php index 039d758..78bc452 100644 --- a/src/PHPStan/Rules/NoAssignmentInIfRule.php +++ b/src/PHPStan/Rules/NoAssignmentInIfRule.php @@ -19,7 +19,7 @@ */ class NoAssignmentInIfRule implements Rule { - private NodeFinder $nodeFinder; + private readonly NodeFinder $nodeFinder; public function __construct() { diff --git a/src/PHPStan/Rules/ThrowableClassNameRule.php b/src/PHPStan/Rules/ThrowableClassNameRule.php index 30c211f..6b01640 100644 --- a/src/PHPStan/Rules/ThrowableClassNameRule.php +++ b/src/PHPStan/Rules/ThrowableClassNameRule.php @@ -13,13 +13,9 @@ /** @implements Rule */ class ThrowableClassNameRule implements Rule { - private ReflectionProvider $reflectionProvider; - public function __construct( - ReflectionProvider $reflectionProvider - ) { - $this->reflectionProvider = $reflectionProvider; - } + private readonly ReflectionProvider $reflectionProvider + ) {} public function getNodeType(): string { diff --git a/src/Qiaxcel/QiaxcelImport.php b/src/Qiaxcel/QiaxcelImport.php index 2bd5cb9..c6260e0 100644 --- a/src/Qiaxcel/QiaxcelImport.php +++ b/src/Qiaxcel/QiaxcelImport.php @@ -9,23 +9,12 @@ class QiaxcelImport { - public string $fileName; - - /** @var list */ - protected array $entries; - - public string $valueForEmptyCell; - /** @param list $entries */ public function __construct( - string $fileName, - array $entries, - string $valueForEmptyCell = 'Leer' - ) { - $this->fileName = $fileName; - $this->entries = $entries; - $this->valueForEmptyCell = $valueForEmptyCell; - } + public string $fileName, + protected array $entries, + public string $valueForEmptyCell = 'Leer' + ) {} public function generate(): SpreadSheet { diff --git a/src/QxManager/FilledRow.php b/src/QxManager/FilledRow.php index 5ba9b60..1b4aef5 100644 --- a/src/QxManager/FilledRow.php +++ b/src/QxManager/FilledRow.php @@ -4,73 +4,24 @@ class FilledRow { - private string $experimentType; - - private string $supermixName; - - private string $assayType; - - private string $targetType; - - private string $plot; - - private string $targetName; - - private string $signalCh1; - - private string $signalCh2; - - private string $sampleDescription1; - - private ?string $sampleDescription2; - - private ?string $sampleDescription3; - - private ?string $sampleDescription4; - - private string $sampleType; - - private ?int $referenceCopies; - - private ?string $wellNotes; - - private ?string $rdqConversionFactor; - public function __construct( - string $sampleDescription1, - ?string $sampleDescription2, - ?string $sampleDescription3, - ?string $sampleDescription4, - string $sampleType, - string $experimentType, - string $supermixName, - string $assayType, - string $targetType, - string $plot, - string $targetName, - string $signalCh1, - string $signalCh2, - ?int $referenceCopies = null, - ?string $wellNotes = null, - ?string $rdqConversionFactor = null - ) { - $this->targetName = $targetName; - $this->signalCh1 = $signalCh1; - $this->signalCh2 = $signalCh2; - $this->sampleDescription1 = $sampleDescription1; - $this->sampleDescription2 = $sampleDescription2; - $this->sampleDescription3 = $sampleDescription3; - $this->sampleDescription4 = $sampleDescription4; - $this->sampleType = $sampleType; - $this->experimentType = $experimentType; - $this->supermixName = $supermixName; - $this->assayType = $assayType; - $this->targetType = $targetType; - $this->plot = $plot; - $this->referenceCopies = $referenceCopies; - $this->wellNotes = $wellNotes; - $this->rdqConversionFactor = $rdqConversionFactor; - } + private readonly string $sampleDescription1, + private readonly ?string $sampleDescription2, + private readonly ?string $sampleDescription3, + private readonly ?string $sampleDescription4, + private readonly string $sampleType, + private readonly string $experimentType, + private readonly string $supermixName, + private readonly string $assayType, + private readonly string $targetType, + private readonly string $plot, + private readonly string $targetName, + private readonly string $signalCh1, + private readonly string $signalCh2, + private readonly ?int $referenceCopies = null, + private readonly ?string $wellNotes = null, + private readonly ?string $rdqConversionFactor = null + ) {} public function toString(): string { diff --git a/src/QxManager/FilledWell.php b/src/QxManager/FilledWell.php index bd4da93..ee3bf67 100644 --- a/src/QxManager/FilledWell.php +++ b/src/QxManager/FilledWell.php @@ -7,15 +7,10 @@ class FilledWell { - private FilledRow $famRow; - - private FilledRow $hexRow; - - public function __construct(FilledRow $famRow, FilledRow $hexRow) - { - $this->famRow = $famRow; - $this->hexRow = $hexRow; - } + public function __construct( + private readonly FilledRow $famRow, + private readonly FilledRow $hexRow + ) {} /** @param Coordinates $coordinates */ public function toString(Coordinates $coordinates): string diff --git a/src/Tecan/BasicCommands/AspirateAndDispenseParameters.php b/src/Tecan/BasicCommands/AspirateAndDispenseParameters.php index a918400..572d74f 100644 --- a/src/Tecan/BasicCommands/AspirateAndDispenseParameters.php +++ b/src/Tecan/BasicCommands/AspirateAndDispenseParameters.php @@ -6,18 +6,11 @@ class AspirateAndDispenseParameters { - private Rack $rack; - - private int $startPosition; - - private int $endPosition; - - public function __construct(Rack $rack, int $startPosition, int $endPosition) - { - $this->rack = $rack; - $this->startPosition = $startPosition; - $this->endPosition = $endPosition; - } + public function __construct( + private readonly Rack $rack, + private readonly int $startPosition, + private readonly int $endPosition + ) {} /** Serializes the aspirate and dispense parameters as part of a reagent distribution according the gwl file format. */ public function toString(): string diff --git a/src/Tecan/BasicCommands/Comment.php b/src/Tecan/BasicCommands/Comment.php index 9d8f3b9..adebcc2 100644 --- a/src/Tecan/BasicCommands/Comment.php +++ b/src/Tecan/BasicCommands/Comment.php @@ -4,12 +4,9 @@ class Comment extends Command { - private string $comment; - - public function __construct(string $comment) - { - $this->comment = $comment; - } + public function __construct( + private readonly string $comment + ) {} public function toString(): string { diff --git a/src/Tecan/BasicCommands/ReagentDistribution.php b/src/Tecan/BasicCommands/ReagentDistribution.php index 38ff826..beeb2fb 100644 --- a/src/Tecan/BasicCommands/ReagentDistribution.php +++ b/src/Tecan/BasicCommands/ReagentDistribution.php @@ -7,22 +7,7 @@ class ReagentDistribution extends Command { - private AspirateAndDispenseParameters $source; - - private AspirateAndDispenseParameters $target; - - private float $volume; - - private LiquidClass $liquidClass; - - private ?int $numberOfDitiReuses; - - private ?int $numberOfMultiDisp; - - private ReagentDistributionDirection $direction; - - /** @var array|null */ - private ?array $excludedTargetWells; + private readonly ReagentDistributionDirection $direction; /** * @param int|null $numberOfDitiReuses optional maximum number of DiTi reuses allowed (default 1 = no DiTi reuse) @@ -31,23 +16,16 @@ class ReagentDistribution extends Command * @param array|null $excludedTargetWells Optional list of wells in destination labware to be excluded from pipetting */ public function __construct( - AspirateAndDispenseParameters $source, - AspirateAndDispenseParameters $target, - float $dispenseVolume, - LiquidClass $liquidClass, - ?int $numberOfDitiReuses = null, - ?int $numberOfMultiDisp = null, + private readonly AspirateAndDispenseParameters $source, + private readonly AspirateAndDispenseParameters $target, + private readonly float $volume, + private readonly LiquidClass $liquidClass, + private readonly ?int $numberOfDitiReuses = null, + private readonly ?int $numberOfMultiDisp = null, ?ReagentDistributionDirection $direction = null, - ?array $excludedTargetWells = null + private readonly ?array $excludedTargetWells = null ) { - $this->source = $source; - $this->target = $target; - $this->volume = $dispenseVolume; - $this->liquidClass = $liquidClass; - $this->numberOfDitiReuses = $numberOfDitiReuses; - $this->numberOfMultiDisp = $numberOfMultiDisp; $this->direction = $direction ?? ReagentDistributionDirection::LEFT_TO_RIGHT(); - $this->excludedTargetWells = $excludedTargetWells; } public function toString(): string diff --git a/src/Tecan/BasicCommands/SetDiTiType.php b/src/Tecan/BasicCommands/SetDiTiType.php index ca0ccdb..094b91b 100644 --- a/src/Tecan/BasicCommands/SetDiTiType.php +++ b/src/Tecan/BasicCommands/SetDiTiType.php @@ -9,12 +9,9 @@ */ class SetDiTiType extends Command { - private int $indexOfDiTi; - - public function __construct(int $indexOfDiTi) - { - $this->indexOfDiTi = $indexOfDiTi; - } + public function __construct( + private readonly int $indexOfDiTi + ) {} public function toString(): string { diff --git a/src/Tecan/CustomCommands/AspirateParameters.php b/src/Tecan/CustomCommands/AspirateParameters.php index 070b01f..6c1230d 100644 --- a/src/Tecan/CustomCommands/AspirateParameters.php +++ b/src/Tecan/CustomCommands/AspirateParameters.php @@ -7,15 +7,10 @@ class AspirateParameters { - private Rack $rack; - - private int $sourcePosition; - - public function __construct(Rack $rack, int $sourcePosition) - { - $this->rack = $rack; - $this->sourcePosition = $sourcePosition; - } + public function __construct( + private readonly Rack $rack, + private readonly int $sourcePosition + ) {} public function formatToAspirateAndDispenseParameters(): AspirateAndDispenseParameters { diff --git a/src/Tecan/CustomCommands/DispenseParameters.php b/src/Tecan/CustomCommands/DispenseParameters.php index 2dbfd56..8b90d12 100644 --- a/src/Tecan/CustomCommands/DispenseParameters.php +++ b/src/Tecan/CustomCommands/DispenseParameters.php @@ -7,17 +7,11 @@ class DispenseParameters { - public Rack $rack; - - /** @var non-empty-array */ - public array $dispensePositions; - /** @param non-empty-array $dispensePositions */ - public function __construct(Rack $rack, array $dispensePositions) - { - $this->rack = $rack; - $this->dispensePositions = $dispensePositions; - } + public function __construct( + public Rack $rack, + public array $dispensePositions + ) {} public function formatToAspirateAndDispenseParameters(): AspirateAndDispenseParameters { diff --git a/src/Tecan/CustomCommands/MLLReagentDistribution.php b/src/Tecan/CustomCommands/MLLReagentDistribution.php index 49c2c4b..e6b7661 100644 --- a/src/Tecan/CustomCommands/MLLReagentDistribution.php +++ b/src/Tecan/CustomCommands/MLLReagentDistribution.php @@ -12,25 +12,12 @@ class MLLReagentDistribution extends Command public const NUMBER_OF_DITI_REUSES = 6; public const NUMBER_OF_MULTI_DISP = 1; - private AspirateParameters $source; - - private DispenseParameters $target; - - private float $volume; - - private LiquidClass $liquidClass; - public function __construct( - AspirateParameters $source, - DispenseParameters $target, - float $dispenseVolume, - LiquidClass $liquidClass - ) { - $this->source = $source; - $this->target = $target; - $this->volume = $dispenseVolume; - $this->liquidClass = $liquidClass; - } + private readonly AspirateParameters $source, + private readonly DispenseParameters $target, + private readonly float $volume, + private readonly LiquidClass $liquidClass + ) {} public function toString(): string { diff --git a/src/Tecan/CustomCommands/TransferWithAutoWash.php b/src/Tecan/CustomCommands/TransferWithAutoWash.php index 8b46b4d..515841d 100644 --- a/src/Tecan/CustomCommands/TransferWithAutoWash.php +++ b/src/Tecan/CustomCommands/TransferWithAutoWash.php @@ -13,9 +13,9 @@ class TransferWithAutoWash extends Command implements UsesTipMask { - private Aspirate $aspirate; + private readonly Aspirate $aspirate; - private Dispense $dispense; + private readonly Dispense $dispense; public function __construct(float $volume, LiquidClass $liquidClass, Location $aspirateLocation, Location $dispenseLocation) { diff --git a/src/Tecan/LiquidClass/CustomLiquidClass.php b/src/Tecan/LiquidClass/CustomLiquidClass.php index 336f17e..365f88c 100644 --- a/src/Tecan/LiquidClass/CustomLiquidClass.php +++ b/src/Tecan/LiquidClass/CustomLiquidClass.php @@ -4,12 +4,9 @@ class CustomLiquidClass implements LiquidClass { - private string $name; - - public function __construct(string $name) - { - $this->name = $name; - } + public function __construct( + private readonly string $name + ) {} public function name(): string { diff --git a/src/Tecan/LiquidClass/MLLLiquidClass.php b/src/Tecan/LiquidClass/MLLLiquidClass.php index 3ddd39d..3fd0264 100644 --- a/src/Tecan/LiquidClass/MLLLiquidClass.php +++ b/src/Tecan/LiquidClass/MLLLiquidClass.php @@ -8,14 +8,11 @@ class MLLLiquidClass implements LiquidClass public const DNA_DILUTION_WATER = 'DNA_Dilution_Water'; public const TRANSFER_PCR_PRODUKT = 'Transfer_PCR_Produkt'; public const TRANSFER_MASTERMIX_MP = 'Transfer_Mastermix_MP'; - public const TRANSFER_TEMPLATE = 'Transfer_Template'; // DNA-templates and BUFFER! + public const TRANSFER_TEMPLATE = 'Transfer_Template'; - public string $value; - - public function __construct(string $value) - { - $this->value = $value; - } + public function __construct( + public string $value + ) {} public static function DNA_DILUTION(): self { diff --git a/src/Tecan/Location/BarcodeLocation.php b/src/Tecan/Location/BarcodeLocation.php index 8d1d87d..d77026c 100644 --- a/src/Tecan/Location/BarcodeLocation.php +++ b/src/Tecan/Location/BarcodeLocation.php @@ -6,15 +6,10 @@ class BarcodeLocation implements Location { - private string $barcode; - - private ScannedRack $rack; - - public function __construct(string $barcode, ScannedRack $rack) - { - $this->barcode = $barcode; - $this->rack = $rack; - } + public function __construct( + private readonly string $barcode, + private readonly ScannedRack $rack + ) {} public function tubeID(): string { diff --git a/src/Tecan/Location/PositionLocation.php b/src/Tecan/Location/PositionLocation.php index 25601dc..d86f261 100644 --- a/src/Tecan/Location/PositionLocation.php +++ b/src/Tecan/Location/PositionLocation.php @@ -6,15 +6,10 @@ class PositionLocation implements Location { - private int $position; - - private Rack $rack; - - public function __construct(int $position, Rack $rack) - { - $this->position = $position; - $this->rack = $rack; - } + public function __construct( + private readonly int $position, + private readonly Rack $rack + ) {} public function tubeID(): ?string { diff --git a/src/Tecan/Rack/BaseRack.php b/src/Tecan/Rack/BaseRack.php index 9f0e9e8..ad2ff91 100644 --- a/src/Tecan/Rack/BaseRack.php +++ b/src/Tecan/Rack/BaseRack.php @@ -13,11 +13,9 @@ abstract class BaseRack implements Rack /** @var Collection */ public Collection $positions; - public CoordinateSystem $coordinateSystem; - - public function __construct(CoordinateSystem $coordinateSystem) - { - $this->coordinateSystem = $coordinateSystem; + public function __construct( + public CoordinateSystem $coordinateSystem + ) { /** @phpstan-ignore-next-line types are correct, but phpstan doesn't understand it */ $this->positions = Collection::times($this->positionCount(), fn () => self::EMPTY_POSITION) ->mapWithKeys(fn ($content, int $position): array => [$position + 1 => $content]); /** @phpstan-ignore missingType.parameter (is in template context) */ diff --git a/src/Tecan/ReagentDistribution/ReagentDistributionDirection.php b/src/Tecan/ReagentDistribution/ReagentDistributionDirection.php index 1c0785f..b61cb1d 100644 --- a/src/Tecan/ReagentDistribution/ReagentDistributionDirection.php +++ b/src/Tecan/ReagentDistribution/ReagentDistributionDirection.php @@ -7,12 +7,9 @@ class ReagentDistributionDirection public const LEFT_TO_RIGHT = 0; public const RIGHT_TO_LEFT = 1; - public int $value; - - public function __construct(int $value) - { - $this->value = $value; - } + public function __construct( + public int $value + ) {} public static function LEFT_TO_RIGHT(): self { diff --git a/src/Tecan/TecanProtocol.php b/src/Tecan/TecanProtocol.php index 0b5e255..94c0038 100644 --- a/src/Tecan/TecanProtocol.php +++ b/src/Tecan/TecanProtocol.php @@ -22,28 +22,22 @@ class TecanProtocol public const GEMINI_WORKLIST_FILENAME_SUFFIX = '.gwl'; - private TipMask $tipMask; - - private string $protocolName; + private readonly string $protocolName; /** @var Collection */ - private Collection $commands; - - public ?int $defaultDiTiTypeIndex; + private readonly Collection $commands; public ?int $currentDiTiTypeIndex; public function __construct( - TipMask $tipMask, + private readonly TipMask $tipMask, ?string $protocolName = null, ?string $userName = null, - ?int $defaultDiTiTypeIndex = null + public ?int $defaultDiTiTypeIndex = null ) { - $this->tipMask = $tipMask; $this->protocolName = $protocolName ?? Str::uuid()->toString(); $this->commands = $this->buildHeader($userName, $protocolName); - $this->defaultDiTiTypeIndex = $defaultDiTiTypeIndex; - $this->currentDiTiTypeIndex = $defaultDiTiTypeIndex; + $this->currentDiTiTypeIndex = $this->defaultDiTiTypeIndex; } public function addCommand(Command $command): void diff --git a/src/Tecan/TipMask/TipMask.php b/src/Tecan/TipMask/TipMask.php index 4924ff5..1a3c31d 100644 --- a/src/Tecan/TipMask/TipMask.php +++ b/src/Tecan/TipMask/TipMask.php @@ -9,14 +9,11 @@ class TipMask public const FOUR_TIPS = 'FOUR_TIPS'; public const EIGHT_TIPS = 'EIGHT_TIPS'; - public string $value; - public ?int $currentTip = null; - public function __construct(string $value) - { - $this->value = $value; - } + public function __construct( + public string $value + ) {} public static function FOUR_TIPS(): self { @@ -35,14 +32,11 @@ public static function firstTip(): int public function isLastTip(): bool { - switch ($this->value) { - case self::FOUR_TIPS: - return $this->currentTip === 8; - case self::EIGHT_TIPS: - return $this->currentTip === 128; - default: - throw new TecanException("isLastTip not defined for {$this->value}."); - } + return match ($this->value) { + self::FOUR_TIPS => $this->currentTip === 8, + self::EIGHT_TIPS => $this->currentTip === 128, + default => throw new TecanException("isLastTip not defined for {$this->value}."), + }; } public function nextTip(): int