diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..3bb4178 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://enflow.nl/contact diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml new file mode 100644 index 0000000..a83d708 --- /dev/null +++ b/.github/workflows/php-cs-fixer.yml @@ -0,0 +1,23 @@ +name: Check & fix styling + +on: [push] + +jobs: + php-cs-fixer: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + + - name: Run PHP CS Fixer + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --config=.php-cs-fixer.dist.php --allow-risky=yes + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Fix styling diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..06b4e1e --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,29 @@ +name: run-tests + +on: [push, pull_request] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + php: [8.0, 7.4] + dependency-version: [prefer-lowest, prefer-stable] + + name: P${{ matrix.php }} - ${{ matrix.dependency-version }} - ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip + coverage: none + + - name: Install dependencies + run: composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source diff --git a/.gitignore b/.gitignore index 4f6ebc2..06fe4c7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .phpunit.result.cache composer.lock vendor +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..f5124b6 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,42 @@ +in([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->notPath('bootstrap/*') + ->notPath('storage/*') + ->notPath('resources/view/mail/*') + ->name('*.php') + ->notName('*.blade.php') + ->ignoreDotFiles(true) + ->ignoreVCS(true) +; + +return (new Config()) + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'trailing_comma_in_multiline' => true, + 'phpdoc_scalar' => true, + 'unary_operator_spaces' => true, + 'binary_operator_spaces' => true, + 'blank_line_before_statement' => [ + 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], + ], + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_var_without_name' => true, + 'method_argument_space' => [ + 'on_multiline' => 'ensure_fully_multiline', + 'keep_multiple_spaces_after_comma' => true, + ], + 'single_trait_insert_per_statement' => true, + ]) + ->setFinder($finder); diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 89e01a7..0000000 --- a/.php_cs +++ /dev/null @@ -1,13 +0,0 @@ -exclude('vendor') - ->in(__DIR__); - -return Symfony\CS\Config\Config::create() - ->setUsingCache(true) - ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) - ->fixers([ - 'short_array_syntax', - ]) - ->finder($finder); diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6844630..0000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: php -dist: xenial - -php: - - 7.2 - - 7.3 - - 7.4 - -sudo: required - -before_install: - - sudo add-apt-repository ppa:libreoffice/ppa -y - - sudo apt-get update -qq - - sudo apt-get install -y libreoffice unoconv - - sudo mkdir -p /home/travis/.config/libreoffice - - sudo chmod 777 /home/travis/.config/libreoffice - -env: - matrix: - - COMPOSER_FLAGS="--prefer-lowest" - -before_script: - - travis_retry composer self-update - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source - -script: - - phpunit diff --git a/composer.json b/composer.json index 06080d7..983c9f1 100644 --- a/composer.json +++ b/composer.json @@ -15,12 +15,13 @@ } ], "require": { - "php": "^7.2.5", - "phpoffice/phpword": "^0.17.0", + "php": "^7.4|^8.0", + "phpoffice/phpword": "^0.18.2", "symfony/process": "^4.2 || ^5.0" }, "require-dev": { - "phpunit/phpunit": "^8.1" + "phpunit/phpunit": "^9.0", + "friendsofphp/php-cs-fixer": "^3.0" }, "autoload": { "psr-4": { @@ -33,6 +34,7 @@ } }, "scripts": { - "test": "vendor/bin/phpunit" + "test": "vendor/bin/phpunit", + "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ec7bfdc..4fadc5b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,22 +1,13 @@ - + + + + src/ + + - + tests - - - src/ - - diff --git a/src/Converters/AbstractConverter.php b/src/Converters/AbstractConverter.php index 68aa3c7..8f3f8ef 100644 --- a/src/Converters/AbstractConverter.php +++ b/src/Converters/AbstractConverter.php @@ -6,7 +6,7 @@ abstract class AbstractConverter { - private $documentReplacer; + private DocumentReplacer $documentReplacer; private function __construct(DocumentReplacer $documentReplacer) { diff --git a/src/Converters/UnoconvConverter.php b/src/Converters/UnoconvConverter.php index 5ed9680..e8dc321 100644 --- a/src/Converters/UnoconvConverter.php +++ b/src/Converters/UnoconvConverter.php @@ -7,7 +7,7 @@ class UnoconvConverter extends AbstractConverter { - public $binary = '/usr/bin/unoconv'; + public string $binary = '/usr/bin/unoconv'; public function convert(string $input, string $output): void { @@ -21,11 +21,11 @@ public function convert(string $input, string $output): void $process->mustRun(); // unoconv 0.7 always appends extension to --output filename https://github.com/unoconv/unoconv/issues/307 - if (!pathinfo($output, PATHINFO_EXTENSION) && file_exists($output . '.pdf')) { + if (! pathinfo($output, PATHINFO_EXTENSION) && file_exists($output . '.pdf')) { rename($output . '.pdf', $output); } - if (!file_exists($output)) { + if (! file_exists($output)) { throw new ConversionFailed("Unable to convert document to PDF through unoconv"); } } diff --git a/src/DocumentReplacer.php b/src/DocumentReplacer.php index 62188e1..0b6363c 100644 --- a/src/DocumentReplacer.php +++ b/src/DocumentReplacer.php @@ -2,10 +2,10 @@ namespace Enflow\DocumentReplacer; +use Enflow\DocumentReplacer\Converters\AbstractConverter; use Enflow\DocumentReplacer\Exceptions\InvalidReplacement; use Exception; use PhpOffice\PhpWord\TemplateProcessor; -use Enflow\DocumentReplacer\Converters\AbstractConverter; class DocumentReplacer { @@ -30,8 +30,9 @@ public function replace(array $keyValue): self if ($value instanceof ValueTypes\Image) { $this->templateProcessor->setImageValue($key, $value->replacements()); } else { - if (!is_scalar($value) && $value !== null) { + if (! is_scalar($value) && $value !== null) { $type = gettype($value); + throw new InvalidReplacement("Could not replace '{$key}' in template. Value must be non-scalar or null. Type is: {$type}"); } @@ -61,7 +62,7 @@ public function save(string $outputPath): string $class::make($this)->convert($temporaryFile, $outputPath); - if (!file_exists($outputPath) || !filesize($outputPath)) { + if (! file_exists($outputPath) || ! filesize($outputPath)) { throw new Exception("Converter failed to output valid file to {$outputPath}"); } diff --git a/src/Template.php b/src/Template.php index d6298b1..bdb87f9 100644 --- a/src/Template.php +++ b/src/Template.php @@ -8,11 +8,11 @@ class Template { private function __construct(string $path) { - if (!file_exists($path)) { + if (! file_exists($path)) { throw new InvalidArgumentException("File at '{$path}' cannot be found."); } - if (!is_file($path)) { + if (! is_file($path)) { throw new InvalidArgumentException("File at '{$path}' must be a file."); } diff --git a/src/ValueTypes/Image.php b/src/ValueTypes/Image.php index 5cb5d06..4ad3c50 100644 --- a/src/ValueTypes/Image.php +++ b/src/ValueTypes/Image.php @@ -6,10 +6,12 @@ class Image { + /** @var string|Closure */ private $image; - private $ratio; - private $width; - private $height; + + private ?bool $ratio = null; + private ?int $width = null; + private ?int $height = null; private function __construct($image) { diff --git a/tests/ImageValueTypeTest.php b/tests/ImageValueTypeTest.php index b8b990d..781b761 100644 --- a/tests/ImageValueTypeTest.php +++ b/tests/ImageValueTypeTest.php @@ -2,8 +2,6 @@ namespace Enflow\DocumentReplacer\Test; -use Enflow\DocumentReplacer\Converters\UnoconvConverter; -use Enflow\DocumentReplacer\DocumentReplacer; use Enflow\DocumentReplacer\ValueTypes\Image; use PHPUnit\Framework\TestCase; @@ -16,20 +14,26 @@ public function test_image_create_from_path() public function test_image_create_from_base64_with_prefix() { - $this->assertEquals('4e7e0753fd7068d368bbe516f09e321a', - Image::forBase64('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB8SURBVDhP3YxBDoAgDAR5iEf//zPfgCutCGwp4MXEyZI0W6bh2PaYyMM8Aa/0l05UsjDvGzIoG+fWJQPHfyMDKccy4E9oOLpLeLLQ9OWJRwamz2VXNqPrm1xWMjB/M56coy0hK0PWKdHz5fRABj0f/Efm6I5o5SW+kmM8AS/fakEk7YJkAAAAAElFTkSuQmCC')->signature()); + $this->assertEquals( + '4e7e0753fd7068d368bbe516f09e321a', + Image::forBase64('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB8SURBVDhP3YxBDoAgDAR5iEf//zPfgCutCGwp4MXEyZI0W6bh2PaYyMM8Aa/0l05UsjDvGzIoG+fWJQPHfyMDKccy4E9oOLpLeLLQ9OWJRwamz2VXNqPrm1xWMjB/M56coy0hK0PWKdHz5fRABj0f/Efm6I5o5SW+kmM8AS/fakEk7YJkAAAAAElFTkSuQmCC')->signature() + ); } public function test_image_create_from_base64_without_prefix() { - $this->assertEquals('4e7e0753fd7068d368bbe516f09e321a', - Image::forBase64('iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB8SURBVDhP3YxBDoAgDAR5iEf//zPfgCutCGwp4MXEyZI0W6bh2PaYyMM8Aa/0l05UsjDvGzIoG+fWJQPHfyMDKccy4E9oOLpLeLLQ9OWJRwamz2VXNqPrm1xWMjB/M56coy0hK0PWKdHz5fRABj0f/Efm6I5o5SW+kmM8AS/fakEk7YJkAAAAAElFTkSuQmCC')->signature()); + $this->assertEquals( + '4e7e0753fd7068d368bbe516f09e321a', + Image::forBase64('iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB8SURBVDhP3YxBDoAgDAR5iEf//zPfgCutCGwp4MXEyZI0W6bh2PaYyMM8Aa/0l05UsjDvGzIoG+fWJQPHfyMDKccy4E9oOLpLeLLQ9OWJRwamz2VXNqPrm1xWMjB/M56coy0hK0PWKdHz5fRABj0f/Efm6I5o5SW+kmM8AS/fakEk7YJkAAAAAElFTkSuQmCC')->signature() + ); } public function test_image_create_from_binary() { - $this->assertEquals('4e7e0753fd7068d368bbe516f09e321a', - Image::forBinary(base64_decode('iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB8SURBVDhP3YxBDoAgDAR5iEf//zPfgCutCGwp4MXEyZI0W6bh2PaYyMM8Aa/0l05UsjDvGzIoG+fWJQPHfyMDKccy4E9oOLpLeLLQ9OWJRwamz2VXNqPrm1xWMjB/M56coy0hK0PWKdHz5fRABj0f/Efm6I5o5SW+kmM8AS/fakEk7YJkAAAAAElFTkSuQmCC'))->signature()); + $this->assertEquals( + '4e7e0753fd7068d368bbe516f09e321a', + Image::forBinary(base64_decode('iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB8SURBVDhP3YxBDoAgDAR5iEf//zPfgCutCGwp4MXEyZI0W6bh2PaYyMM8Aa/0l05UsjDvGzIoG+fWJQPHfyMDKccy4E9oOLpLeLLQ9OWJRwamz2VXNqPrm1xWMjB/M56coy0hK0PWKdHz5fRABj0f/Efm6I5o5SW+kmM8AS/fakEk7YJkAAAAAElFTkSuQmCC'))->signature() + ); } public function test_image_create_lazy() diff --git a/tests/TemplateTest.php b/tests/TemplateTest.php index 6458eec..4f990ea 100644 --- a/tests/TemplateTest.php +++ b/tests/TemplateTest.php @@ -2,8 +2,6 @@ namespace Enflow\DocumentReplacer\Test; -use Enflow\DocumentReplacer\Converters\UnoconvConverter; -use Enflow\DocumentReplacer\DocumentReplacer; use Enflow\DocumentReplacer\Template; use PHPUnit\Framework\TestCase;